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