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