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