]> www.ginac.de Git - cln.git/blob - include/cln/GV.h
Add support for x86_64 CPU.
[cln.git] / include / cln / GV.h
1 // General vectors.
2
3 #ifndef _CL_GV_H
4 #define _CL_GV_H
5
6 #include "cln/object.h"
7 #include "cln/V.h"
8 #include "cln/abort.h"
9 #include <stdlib.h>
10
11 namespace cln {
12
13 // A vector is a structure having the following interface:
14 //     v.length()        returns the number of elements
15 //     v[i]              returns the i-th element (0<=i<length), as a
16 //                       pseudo-lvalue (you can assign to it, but not take its
17 //                       address - exactly what you want for bit-vectors)
18 // This is implemented by letting v[i] be of a special "vector index" type.
19
20 template <class T> class cl_GV_inner;
21 template <class T> class cl_GV_index;
22 template <class T> class cl_GV_constindex;
23 template <class T> struct cl_GV_vectorops;
24
25 template <class T>
26 class cl_GV_inner {
27 protected:
28         uintL len; // number of elements
29 public:
30         uintL length () const; // number of elements
31         cl_GV_vectorops<T>* vectorops; // get/set element
32         const cl_GV_index<T> operator[] (unsigned long index);
33         const cl_GV_constindex<T> operator[] (unsigned long index) const;
34         const cl_GV_index<T> operator[] (long index);
35         const cl_GV_constindex<T> operator[] (long index) const;
36         const cl_GV_index<T> operator[] (unsigned int index);
37         const cl_GV_constindex<T> operator[] (unsigned int index) const;
38         const cl_GV_index<T> operator[] (int index);
39         const cl_GV_constindex<T> operator[] (int index) const;
40 public: /* ugh */
41         // Constructor.
42         cl_GV_inner (uintL l, cl_GV_vectorops<T>* ops) : len (l), vectorops (ops) {}
43 public:
44         // Destructor.
45         ~cl_GV_inner ();
46         // Ability to place an object at a given address.
47         void* operator new (size_t size, void* ptr) { (void)size; return ptr; }
48 private:
49 // No default constructor, copy constructor, assignment operator, new.
50         cl_GV_inner ();
51         cl_GV_inner (const cl_GV_inner&);
52         cl_GV_inner& operator= (const cl_GV_inner&);
53         void* operator new (size_t size)
54                 { (void)size; return (void*)1; } // SGI CC needs this definition
55 // Friend declarations. They are for the compiler. Just ignore them.
56         friend class cl_GV_index<T>;
57         friend class cl_GV_constindex<T>;
58 };
59
60 template <class T>
61 class cl_GV_index {
62         // This is the class of objects created by accessing a non-const vector
63         // through [].
64 public:
65         cl_GV_inner<T>* vec;
66         uintL index;
67         operator T () const;
68         // Constructor:
69         cl_GV_index (cl_GV_inner<T>* v, uintL i) : vec (v), index (i) {}
70         // Assignment operator.
71         void operator= (const T& x) const;
72 #if (defined(__sparc__) || defined(__sparc64__) || defined(__mips__) || defined(__mips64__)) && !defined(__GNUC__) // maybe an SGI CC and Sun CC bug?
73         void operator= (const cl_GV_index<T>&) const;
74         void operator= (const cl_GV_constindex<T>&) const;
75 #else
76 private:
77         // No assignment operator.
78         cl_GV_index& operator= (const cl_GV_index&);
79 #endif
80 private:
81 // No default constructor.
82         cl_GV_index ();
83 };
84
85 template <class T>
86 class cl_GV_constindex {
87         // This is the class of objects created by accessing a const vector
88         // through []. It lacks the assignment operator.
89 public:
90         const cl_GV_inner<T>* vec;
91         uintL index;
92         operator T () const;
93         // Constructor:
94         cl_GV_constindex (const cl_GV_inner<T>* v, uintL i) : vec (v), index (i) {}
95 private:
96 // No default constructor, assignment operator.
97         cl_GV_constindex ();
98         cl_GV_constindex& operator= (const cl_GV_constindex&);
99 };
100
101 template <class T>
102 struct cl_GV_vectorops {
103         const T (*element) (const cl_GV_inner<T>* vec, uintL index);
104         void (*set_element) (cl_GV_inner<T>* vec, uintL index, const T& x);
105         void (*do_delete) (cl_GV_inner<T>* vec);
106         void (*copy_elements) (const cl_GV_inner<T>* srcvec, uintL srcindex, cl_GV_inner<T>* destvec, uintL destindex, uintL count);
107 };
108
109 // All member functions are inline.
110
111 template <class T>
112 inline uintL cl_GV_inner<T>::length () const
113 {
114         return len;
115 }
116
117 template <class T>
118 inline const cl_GV_index<T> cl_GV_inner<T>::operator[] (unsigned long index)
119 {
120         return cl_GV_index<T>(this,index);
121 }
122
123 template <class T>
124 inline const cl_GV_constindex<T> cl_GV_inner<T>::operator[] (unsigned long index) const
125 {
126         return cl_GV_constindex<T>(this,index);
127 }
128
129 template <class T>
130 inline const cl_GV_index<T> cl_GV_inner<T>::operator[] (long index)
131 {
132         return operator[]((unsigned long)index);
133 }
134
135 template <class T>
136 inline const cl_GV_constindex<T> cl_GV_inner<T>::operator[] (long index) const
137 {
138         return operator[]((unsigned long)index);
139 }
140
141 template <class T>
142 inline const cl_GV_index<T> cl_GV_inner<T>::operator[] (unsigned int index)
143 {
144         return operator[]((unsigned long)index);
145 }
146
147 template <class T>
148 inline const cl_GV_constindex<T> cl_GV_inner<T>::operator[] (unsigned int index) const
149 {
150         return operator[]((unsigned long)index);
151 }
152
153 template <class T>
154 inline const cl_GV_index<T> cl_GV_inner<T>::operator[] (int index)
155 {
156         return operator[]((unsigned long)index);
157 }
158
159 template <class T>
160 inline const cl_GV_constindex<T> cl_GV_inner<T>::operator[] (int index) const
161 {
162         return operator[]((unsigned long)index);
163 }
164
165 template <class T>
166 inline cl_GV_inner<T>::~cl_GV_inner ()
167 {
168         vectorops->do_delete(this);
169 }
170
171 template <class T>
172 inline cl_GV_index<T>::operator T () const
173 {
174         #ifndef CL_GV_NO_RANGECHECKS
175         if (!(index < vec->len)) cl_abort();
176         #endif
177         return vec->vectorops->element(vec,index);
178 }
179
180 template <class T>
181 inline void cl_GV_index<T>::operator= (const T& x) const
182 {
183         #ifndef CL_GV_NO_RANGECHECKS
184         if (!(index < vec->len)) cl_abort();
185         #endif
186         vec->vectorops->set_element(vec,index,x);
187 }
188
189 template <class T>
190 inline cl_GV_constindex<T>::operator T () const
191 {
192         #ifndef CL_GV_NO_RANGECHECKS
193         if (!(index < vec->len)) cl_abort();
194         #endif
195         return vec->vectorops->element(vec,index);
196 }
197
198 #if (defined(__sparc__) || defined(__mips__) || defined(__mips64__)) && !defined(__GNUC__) // maybe an SGI CC and Sun CC bug? handle "y[j] = x[i];"
199 template <class T>
200 inline void cl_GV_index<T>::operator= (const cl_GV_index<T>& x) const
201 { operator= ((T) x); }
202 template <class T>
203 inline void cl_GV_index<T>::operator= (const cl_GV_constindex<T>& x) const
204 { operator= ((T) x); }
205 #endif
206
207
208 // In memory, a vector looks like this:
209
210 template <class T>
211 struct cl_heap_GV : cl_heap {
212         cl_GV_inner<T> v;
213         // here room for the elements
214 };
215
216 // And a reference to a vector always looks like this:
217
218 template <class T, class BASE>
219 struct cl_GV : public BASE {
220 public:
221         // Length.
222         uintL length () const
223         {
224                 return ((const cl_heap_GV<T> *) pointer)->v.length();
225         }
226         // Reference. Forbid modification of `const cl_GV&' arguments.
227         const cl_GV_constindex<T> operator[] (unsigned long index) const
228         {
229                 return ((const cl_heap_GV<T> *) pointer)->v[index];
230         }
231         const cl_GV_index<T> operator[] (unsigned long index)
232         {
233                 return ((cl_heap_GV<T> *) pointer)->v[index];
234         }
235         const cl_GV_constindex<T> operator[] (long index) const
236         { return operator[]((unsigned long)index); }
237         const cl_GV_index<T> operator[] (long index)
238         { return operator[]((unsigned long)index); }
239         const cl_GV_constindex<T> operator[] (unsigned int index) const
240         { return operator[]((unsigned long)index); }
241         const cl_GV_index<T> operator[] (unsigned int index)
242         { return operator[]((unsigned long)index); }
243         const cl_GV_constindex<T> operator[] (int index) const
244         { return operator[]((unsigned long)index); }
245         const cl_GV_index<T> operator[] (int index)
246         { return operator[]((unsigned long)index); }
247         // Copy constructor.
248         cl_GV (const cl_GV&);
249         // Assignment operator.
250         cl_GV& operator= (const cl_GV&);
251         // Copy a piece of a vector into another vector.
252         // (Both vectors must be of the same type. Overlapping not allowed.)
253         static void copy_elements (const cl_GV& src, uintL srcindex, cl_GV& dest, uintL destindex, uintL count)
254         {
255                 const cl_heap_GV<T> * hsrc = (const cl_heap_GV<T> *) src.pointer;
256                 cl_heap_GV<T> * hdest = (cl_heap_GV<T> *) dest.pointer;
257                 if (!(hsrc->v.vectorops == hdest->v.vectorops))
258                         cl_abort();
259                 hsrc->v.vectorops->copy_elements(&hsrc->v,srcindex,&hdest->v,destindex,count);
260         }
261         // Private pointer manipulations.
262         operator cl_heap_GV<T>* () const;
263         cl_GV (cl_heap_GV<T>* p) : BASE ((cl_private_thing) p) {}
264         cl_GV (cl_private_thing p) : BASE (p) {}
265 protected:
266         // Forbid use of default constructor.
267         cl_GV ();
268 };
269 #define CL_GV(T,BASE) cl_GV<T,BASE>
270 // Define copy constructor.
271 template <class T, class BASE>
272         _CL_DEFINE_COPY_CONSTRUCTOR2(CL_GV(T,BASE),cl_GV,BASE)
273 // Define assignment operator.
274 template <class T, class BASE>
275         CL_DEFINE_ASSIGNMENT_OPERATOR(CL_GV(T,BASE),CL_GV(T,BASE))
276 // Private pointer manipulations. Never throw away a `struct cl_heap_GV<T> *'!
277 template <class T, class BASE>
278 inline CL_GV(T,BASE)::operator cl_heap_GV<T>* () const
279 {
280         cl_heap_GV<T>* hpointer = (cl_heap_GV<T>*)pointer;
281         cl_inc_refcount(*this);
282         return hpointer;
283 }
284 #undef CL_GV
285
286 // The "generic" general vector type.
287
288 typedef cl_heap_GV<cl_gcobject> cl_heap_GV_any;
289 typedef cl_GV<cl_gcobject,cl_V_any> cl_GV_any;
290
291
292 // Hack section.
293
294 // Conversions to subtypes without checking:
295   #define The(type)  *(const type *) & cl_identity
296 // This inline function is for type checking purposes only.
297   inline const cl_GV_any& cl_identity (const cl_GV_any& x) { return x; }
298
299 }  // namespace cln
300
301 #endif /* _CL_GV_H */