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