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.

180 lines
5.2 KiB

25 years ago
  1. // Simple vectors.
  2. #ifndef _CL_SV_H
  3. #define _CL_SV_H
  4. #include "cl_object.h"
  5. #include "cl_V.h"
  6. #include "cl_abort.h"
  7. #include <stdlib.h>
  8. // A simple vector has the same operations as a vector, but it can store
  9. // _only_ cl_gcobject's.
  10. // This class is here because the general vectors always need a function
  11. // call for getting/setting the element of a vector. Our main application
  12. // of the general vectors are the bit vectors, needed for implementing
  13. // polynomials over modular integer rings. I don't want that polynomials
  14. // over other rings (in particular cl_I) be penalized by the mere existence
  15. // of polynomials over modular integer rings.
  16. // When the vectors were implemented like this:
  17. //
  18. // cl_GV<cl_I> --> cl_GV<cl_RA> --> cl_GV<cl_R> --> cl_GV<cl_N>
  19. //
  20. // a bit/byte-vector (of integers with limited range) could actually be
  21. // treated correctly by all the functions which manipulate vectors of cl_N.
  22. // This is not crucial, however. Here, we'll have disjoint sets
  23. //
  24. // cl_SV<cl_I> --> cl_SV<cl_RA> --> cl_SV<cl_R> --> cl_SV<cl_N>
  25. //
  26. // cl_GV<cl_I>
  27. //
  28. // i.e. the functions which manipulate a (simple!) vector of cl_N cannot
  29. // deal with a bit/byte-vector.
  30. // (This is the same issue as UPGRADED-ARRAY-ELEMENT-TYPE in Common Lisp.)
  31. template <class T> class cl_SV_inner;
  32. template <class T>
  33. class cl_SV_inner {
  34. protected:
  35. uintL len; // number of elements
  36. private:
  37. // T data[]; // the elements
  38. T * data() { return (T *) (this+1); }
  39. const T * data() const { return (const T *) (this+1); }
  40. public:
  41. uintL length () const { return len; } // number of elements
  42. const T & operator[] (unsigned long index) const
  43. {
  44. #ifndef CL_SV_NO_RANGECHECKS
  45. if (!(index < length())) cl_abort();
  46. #endif
  47. return data()[index];
  48. }
  49. T & operator[] (unsigned long index)
  50. {
  51. #ifndef CL_SV_NO_RANGECHECKS
  52. if (!(index < length())) cl_abort();
  53. #endif
  54. return data()[index];
  55. }
  56. // New ANSI C++ compilers also want the following.
  57. const T & operator[] (unsigned int index) const
  58. { return operator[]((unsigned long)index); }
  59. T & operator[] (unsigned int index)
  60. { return operator[]((unsigned long)index); }
  61. const T & operator[] (long index) const
  62. { return operator[]((unsigned long)index); }
  63. T & operator[] (long index)
  64. { return operator[]((unsigned long)index); }
  65. const T & operator[] (int index) const
  66. { return operator[]((unsigned long)index); }
  67. T & operator[] (int index)
  68. { return operator[]((unsigned long)index); }
  69. public: /* ugh */
  70. // Constructor.
  71. cl_SV_inner (uintL l) : len (l) {}
  72. public:
  73. // Destructor.
  74. ~cl_SV_inner ();
  75. // Ability to place an object at a given address.
  76. void* operator new (size_t size, cl_SV_inner* ptr) { (void)size; return ptr; }
  77. private:
  78. // No default constructor, copy constructor, assignment operator, new.
  79. cl_SV_inner ();
  80. cl_SV_inner (const cl_SV_inner&);
  81. cl_SV_inner& operator= (const cl_SV_inner&);
  82. void* operator new (size_t size);
  83. };
  84. // All member functions are inline.
  85. template <class T>
  86. inline cl_SV_inner<T>::~cl_SV_inner ()
  87. {
  88. uintL i = len;
  89. while (i > 0) {
  90. i--;
  91. data()[i].~T();
  92. }
  93. }
  94. // In memory, a simple vector looks like this:
  95. template <class T>
  96. struct cl_heap_SV : cl_heap {
  97. cl_SV_inner<T> v;
  98. // here room for the elements
  99. };
  100. template <class T, class BASE>
  101. struct cl_SV : public BASE {
  102. public:
  103. // Length.
  104. uintL length () const
  105. {
  106. return ((const cl_heap_SV<T> *) pointer)->v.length();
  107. }
  108. // Reference. Forbid modification of `const cl_SV&' arguments.
  109. const T & operator[] (unsigned long index) const
  110. {
  111. return ((const cl_heap_SV<T> *) pointer)->v[index];
  112. }
  113. T & operator[] (unsigned long index)
  114. {
  115. return ((cl_heap_SV<T> *) pointer)->v[index];
  116. }
  117. // New ANSI C++ compilers also want the following.
  118. const T & operator[] (unsigned int index) const
  119. { return operator[]((unsigned long)index); }
  120. T & operator[] (unsigned int index)
  121. { return operator[]((unsigned long)index); }
  122. const T & operator[] (long index) const
  123. { return operator[]((unsigned long)index); }
  124. T & operator[] (long index)
  125. { return operator[]((unsigned long)index); }
  126. const T & operator[] (int index) const
  127. { return operator[]((unsigned long)index); }
  128. T & operator[] (int index)
  129. { return operator[]((unsigned long)index); }
  130. // Constructors.
  131. cl_SV (const cl_SV&);
  132. // Assignment operators.
  133. cl_SV& operator= (const cl_SV&);
  134. // Private pointer manipulations.
  135. cl_SV (cl_heap_SV<T>* p) : BASE ((cl_private_thing)p) {}
  136. cl_SV (cl_private_thing p) : BASE (p) {}
  137. protected:
  138. // Forbid use of default constructor.
  139. cl_SV ();
  140. };
  141. #define CL_SV(T,BASE) cl_SV<T,BASE>
  142. // Define copy constructor.
  143. template <class T, class BASE>
  144. _CL_DEFINE_COPY_CONSTRUCTOR2(CL_SV(T,BASE),cl_SV,BASE)
  145. // Define assignment operator.
  146. template <class T, class BASE>
  147. CL_DEFINE_ASSIGNMENT_OPERATOR(CL_SV(T,BASE),CL_SV(T,BASE))
  148. #undef CL_SV
  149. // The "generic" simple vector type.
  150. typedef cl_heap_SV<cl_gcobject> cl_heap_SV_any;
  151. typedef cl_SV<cl_gcobject,cl_V_any> cl_SV_any;
  152. // Copy a simple vector.
  153. extern const cl_SV_any copy (const cl_SV_any&);
  154. // Hack section.
  155. // Conversions to subtypes without checking:
  156. #define The(type) *(const type *) & cl_identity
  157. // This inline function is for type checking purposes only.
  158. inline const cl_SV_any& cl_identity (const cl_SV_any& x) { return x; }
  159. #endif /* _CL_SV_H */