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.

182 lines
5.2 KiB

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