You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

299 lines
8.8 KiB

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