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
  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 <stdlib.h>
  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> *) 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> *) pointer)->v[index];
  113. }
  114. T & operator[] (unsigned long index)
  115. {
  116. return ((cl_heap_SV<T> *) 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 */