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