6 #include "cln/object.h"
8 #include "cln/exception.h"
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.
23 // When the vectors were implemented like this:
25 // cl_GV<cl_I> --> cl_GV<cl_RA> --> cl_GV<cl_R> --> cl_GV<cl_N>
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
31 // cl_SV<cl_I> --> cl_SV<cl_RA> --> cl_SV<cl_R> --> cl_SV<cl_N>
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.)
39 template <class T> class cl_SV_inner;
44 std::size_t len; // number of elements
46 // T data[]; // the elements
47 T * data() { return (T *) (this+1); }
48 const T * data() const { return (const T *) (this+1); }
50 std::size_t size() const { return len; } // number of elements
51 const T & operator[] (unsigned long index) const
53 #ifndef CL_SV_NO_RANGECHECKS
54 if (!(index < size())) throw runtime_exception();
58 T & operator[] (unsigned long index)
60 #ifndef CL_SV_NO_RANGECHECKS
61 if (!(index < size())) throw runtime_exception();
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
81 #ifndef CL_SV_NO_RANGECHECKS
82 if (!(index < size())) throw runtime_exception();
86 T & operator[] (unsigned long long index)
88 #ifndef CL_SV_NO_RANGECHECKS
89 if (!(index < size())) throw runtime_exception();
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); }
100 cl_SV_inner (std::size_t l) : len (l) {}
104 // Ability to place an object at a given address.
105 void* operator new (size_t size, void* ptr) { (void)size; return ptr; }
107 // No default constructor, copy constructor, assignment operator, new.
109 cl_SV_inner (const cl_SV_inner&);
110 cl_SV_inner& operator= (const cl_SV_inner&);
111 void* operator new (size_t size);
114 // All member functions are inline.
117 inline cl_SV_inner<T>::~cl_SV_inner ()
127 // In memory, a simple vector looks like this:
130 struct cl_heap_SV : cl_heap {
132 // here room for the elements
135 template <class T, class BASE>
136 struct cl_SV : public BASE {
139 std::size_t size() const
141 return ((const cl_heap_SV<T> *) this->pointer)->v.size();
143 // Reference. Forbid modification of `const cl_SV&' arguments.
144 const T & operator[] (unsigned long index) const
146 return ((const cl_heap_SV<T> *) this->pointer)->v[index];
148 T & operator[] (unsigned long index)
150 return ((cl_heap_SV<T> *) this->pointer)->v[index];
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
168 return ((const cl_heap_SV<T> *) this->pointer)->v[index];
170 T & operator[] (unsigned long long index)
172 return ((cl_heap_SV<T> *) this->pointer)->v[index];
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); }
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) {}
187 // Forbid use of default constructor.
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))
199 // The "generic" simple vector type.
201 typedef cl_heap_SV<cl_gcobject> cl_heap_SV_any;
202 typedef cl_SV<cl_gcobject,cl_V_any> cl_SV_any;
204 // Copy a simple vector.
205 extern const cl_SV_any copy (const cl_SV_any&);
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; }
217 #endif /* _CL_SV_H */