6 #include "cln/object.h"
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.
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;
28 uintL len; // number of elements
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;
42 cl_GV_inner (uintL l, cl_GV_vectorops<T>* ops) : len (l), vectorops (ops) {}
46 // Ability to place an object at a given address.
47 void* operator new (size_t size, cl_GV_inner* ptr) { (void)size; return ptr; }
49 // No default constructor, copy constructor, assignment operator, new.
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>;
62 // This is the class of objects created by accessing a non-const vector
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;
77 // No assignment operator.
78 cl_GV_index& operator= (const cl_GV_index&);
81 // No default constructor.
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.
90 const cl_GV_inner<T>* vec;
94 cl_GV_constindex (const cl_GV_inner<T>* v, uintL i) : vec (v), index (i) {}
96 // No default constructor, assignment operator.
98 cl_GV_constindex& operator= (const cl_GV_constindex&);
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);
109 // All member functions are inline.
112 inline uintL cl_GV_inner<T>::length () const
118 inline const cl_GV_index<T> cl_GV_inner<T>::operator[] (unsigned long index)
120 return cl_GV_index<T>(this,index);
124 inline const cl_GV_constindex<T> cl_GV_inner<T>::operator[] (unsigned long index) const
126 return cl_GV_constindex<T>(this,index);
130 inline const cl_GV_index<T> cl_GV_inner<T>::operator[] (long index)
132 return operator[]((unsigned long)index);
136 inline const cl_GV_constindex<T> cl_GV_inner<T>::operator[] (long index) const
138 return operator[]((unsigned long)index);
142 inline const cl_GV_index<T> cl_GV_inner<T>::operator[] (unsigned int index)
144 return operator[]((unsigned long)index);
148 inline const cl_GV_constindex<T> cl_GV_inner<T>::operator[] (unsigned int index) const
150 return operator[]((unsigned long)index);
154 inline const cl_GV_index<T> cl_GV_inner<T>::operator[] (int index)
156 return operator[]((unsigned long)index);
160 inline const cl_GV_constindex<T> cl_GV_inner<T>::operator[] (int index) const
162 return operator[]((unsigned long)index);
166 inline cl_GV_inner<T>::~cl_GV_inner ()
168 vectorops->do_delete(this);
172 inline cl_GV_index<T>::operator T () const
174 #ifndef CL_GV_NO_RANGECHECKS
175 if (!(index < vec->len)) cl_abort();
177 return vec->vectorops->element(vec,index);
181 inline void cl_GV_index<T>::operator= (const T& x) const
183 #ifndef CL_GV_NO_RANGECHECKS
184 if (!(index < vec->len)) cl_abort();
186 vec->vectorops->set_element(vec,index,x);
190 inline cl_GV_constindex<T>::operator T () const
192 #ifndef CL_GV_NO_RANGECHECKS
193 if (!(index < vec->len)) cl_abort();
195 return vec->vectorops->element(vec,index);
198 #if (defined(__sparc__) || defined(__mips__) || defined(__mips64__)) && !defined(__GNUC__) // maybe an SGI CC and Sun CC bug? handle "y[j] = x[i];"
200 inline void cl_GV_index<T>::operator= (const cl_GV_index<T>& x) const
201 { operator= ((T) x); }
203 inline void cl_GV_index<T>::operator= (const cl_GV_constindex<T>& x) const
204 { operator= ((T) x); }
208 // In memory, a vector looks like this:
211 struct cl_heap_GV : cl_heap {
213 // here room for the elements
216 // And a reference to a vector always looks like this:
218 template <class T, class BASE>
219 struct cl_GV : public BASE {
222 uintL length () const
224 return ((const cl_heap_GV<T> *) pointer)->v.length();
226 // Reference. Forbid modification of `const cl_GV&' arguments.
227 const cl_GV_constindex<T> operator[] (unsigned long index) const
229 return ((const cl_heap_GV<T> *) pointer)->v[index];
231 const cl_GV_index<T> operator[] (unsigned long index)
233 return ((cl_heap_GV<T> *) pointer)->v[index];
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); }
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)
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))
259 hsrc->v.vectorops->copy_elements(&hsrc->v,srcindex,&hdest->v,destindex,count);
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) {}
266 // Forbid use of default constructor.
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
280 cl_heap_GV<T>* hpointer = (cl_heap_GV<T>*)pointer;
281 cl_inc_refcount(*this);
286 // The "generic" general vector type.
288 typedef cl_heap_GV<cl_gcobject> cl_heap_GV_any;
289 typedef cl_GV<cl_gcobject,cl_V_any> cl_GV_any;
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; }
301 #endif /* _CL_GV_H */