Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-19 08:08:30

0001 // General vectors.
0002 
0003 #ifndef _CL_GV_H
0004 #define _CL_GV_H
0005 
0006 #include "cln/object.h"
0007 #include "cln/V.h"
0008 #include "cln/exception.h"
0009 #include <cstdlib>
0010 #include <cstddef>
0011 
0012 namespace cln {
0013 
0014 // A vector is a structure having the following interface:
0015 //     v.size()        returns the number of elements
0016 //     v[i]              returns the i-th element (0<=i<length), as a
0017 //                       pseudo-lvalue (you can assign to it, but not take its
0018 //                       address - exactly what you want for bit-vectors)
0019 // This is implemented by letting v[i] be of a special "vector index" type.
0020 
0021 template <class T> class cl_GV_inner;
0022 template <class T> class cl_GV_index;
0023 template <class T> class cl_GV_constindex;
0024 template <class T> struct cl_GV_vectorops;
0025 
0026 template <class T>
0027 class cl_GV_inner {
0028 protected:
0029     std::size_t len; // number of elements
0030 public:
0031     std::size_t size() const; // number of elements
0032     cl_GV_vectorops<T>* vectorops; // get/set element
0033     const cl_GV_index<T> operator[] (unsigned long index);
0034     const cl_GV_constindex<T> operator[] (unsigned long index) const;
0035     const cl_GV_index<T> operator[] (long index);
0036     const cl_GV_constindex<T> operator[] (long index) const;
0037     const cl_GV_index<T> operator[] (unsigned int index);
0038     const cl_GV_constindex<T> operator[] (unsigned int index) const;
0039     const cl_GV_index<T> operator[] (int index);
0040     const cl_GV_constindex<T> operator[] (int index) const;
0041     #if long_bitsize < pointer_bitsize
0042     const cl_GV_index<T> operator[] (unsigned long long index);
0043     const cl_GV_constindex<T> operator[] (unsigned long long index) const;
0044     const cl_GV_index<T> operator[] (long long index);
0045     const cl_GV_constindex<T> operator[] (long long index) const;
0046     #endif
0047 public: /* ugh */
0048     // Constructor.
0049     cl_GV_inner (std::size_t l, cl_GV_vectorops<T>* ops) : len (l), vectorops (ops) {}
0050 public:
0051     // Destructor.
0052     ~cl_GV_inner ();
0053     // Ability to place an object at a given address.
0054     void* operator new (size_t size, void* ptr) { (void)size; return ptr; }
0055 private:
0056 // No default constructor, copy constructor, assignment operator, new.
0057     cl_GV_inner ();
0058     cl_GV_inner (const cl_GV_inner&);
0059     cl_GV_inner& operator= (const cl_GV_inner&);
0060     void* operator new (size_t size)
0061         { (void)size; return (void*)1; } // SGI CC needs this definition
0062 // Friend declarations. They are for the compiler. Just ignore them.
0063     friend class cl_GV_index<T>;
0064     friend class cl_GV_constindex<T>;
0065 };
0066 
0067 template <class T>
0068 class cl_GV_index {
0069     // This is the class of objects created by accessing a non-const vector
0070     // through [].
0071 public:
0072     cl_GV_inner<T>* vec;
0073     std::size_t index;
0074     operator T () const;
0075     // Constructor:
0076     cl_GV_index (cl_GV_inner<T>* v, std::size_t i) : vec (v), index (i) {}
0077     // Assignment operator.
0078     void operator= (const T& x) const;
0079 #if (defined(__sparc__) || defined(__sparc64__) || defined(__mips__) || defined(__mips64__)) && !defined(__GNUC__) // maybe an SGI CC and Sun CC bug?
0080     void operator= (const cl_GV_index<T>&) const;
0081     void operator= (const cl_GV_constindex<T>&) const;
0082 #else
0083 private:
0084     // No assignment operator.
0085     cl_GV_index& operator= (const cl_GV_index&);
0086 #endif
0087 private:
0088 // No default constructor.
0089     cl_GV_index ();
0090 };
0091 
0092 template <class T>
0093 class cl_GV_constindex {
0094     // This is the class of objects created by accessing a const vector
0095     // through []. It lacks the assignment operator.
0096 public:
0097     const cl_GV_inner<T>* vec;
0098     std::size_t index;
0099     operator T () const;
0100     // Constructor:
0101     cl_GV_constindex (const cl_GV_inner<T>* v, std::size_t i) : vec (v), index (i) {}
0102 private:
0103 // No default constructor, assignment operator.
0104     cl_GV_constindex ();
0105     cl_GV_constindex& operator= (const cl_GV_constindex&);
0106 };
0107 
0108 template <class T>
0109 struct cl_GV_vectorops {
0110     const T (*element) (const cl_GV_inner<T>* vec, std::size_t index);
0111     void (*set_element) (cl_GV_inner<T>* vec, std::size_t index, const T& x);
0112     void (*do_delete) (cl_GV_inner<T>* vec);
0113     void (*copy_elements) (const cl_GV_inner<T>* srcvec, std::size_t srcindex, cl_GV_inner<T>* destvec, std::size_t destindex, std::size_t count);
0114 };
0115 
0116 // All member functions are inline.
0117 
0118 template <class T>
0119 inline std::size_t cl_GV_inner<T>::size() const
0120 {
0121     return len;
0122 }
0123 
0124 template <class T>
0125 inline const cl_GV_index<T> cl_GV_inner<T>::operator[] (unsigned long index)
0126 {
0127     return cl_GV_index<T>(this,index);
0128 }
0129 
0130 template <class T>
0131 inline const cl_GV_constindex<T> cl_GV_inner<T>::operator[] (unsigned long index) const
0132 {
0133     return cl_GV_constindex<T>(this,index);
0134 }
0135 
0136 template <class T>
0137 inline const cl_GV_index<T> cl_GV_inner<T>::operator[] (long index)
0138 {
0139     return operator[]((unsigned long)index);
0140 }
0141 
0142 template <class T>
0143 inline const cl_GV_constindex<T> cl_GV_inner<T>::operator[] (long index) const
0144 {
0145     return operator[]((unsigned long)index);
0146 }
0147 
0148 template <class T>
0149 inline const cl_GV_index<T> cl_GV_inner<T>::operator[] (unsigned int index)
0150 {
0151     return operator[]((unsigned long)index);
0152 }
0153 
0154 template <class T>
0155 inline const cl_GV_constindex<T> cl_GV_inner<T>::operator[] (unsigned int index) const
0156 {
0157     return operator[]((unsigned long)index);
0158 }
0159 
0160 template <class T>
0161 inline const cl_GV_index<T> cl_GV_inner<T>::operator[] (int index)
0162 {
0163     return operator[]((unsigned long)index);
0164 }
0165 
0166 template <class T>
0167 inline const cl_GV_constindex<T> cl_GV_inner<T>::operator[] (int index) const
0168 {
0169     return operator[]((unsigned long)index);
0170 }
0171 
0172 #if long_bitsize < pointer_bitsize
0173 
0174 template <class T>
0175 inline const cl_GV_index<T> cl_GV_inner<T>::operator[] (unsigned long long index)
0176 {
0177     return cl_GV_index<T>(this,index);
0178 }
0179 
0180 template <class T>
0181 inline const cl_GV_constindex<T> cl_GV_inner<T>::operator[] (unsigned long long index) const
0182 {
0183     return cl_GV_constindex<T>(this,index);
0184 }
0185 
0186 template <class T>
0187 inline const cl_GV_index<T> cl_GV_inner<T>::operator[] (long long index)
0188 {
0189     return operator[]((unsigned long)index);
0190 }
0191 
0192 template <class T>
0193 inline const cl_GV_constindex<T> cl_GV_inner<T>::operator[] (long long index) const
0194 {
0195     return operator[]((unsigned long)index);
0196 }
0197 
0198 #endif
0199 
0200 template <class T>
0201 inline cl_GV_inner<T>::~cl_GV_inner ()
0202 {
0203     vectorops->do_delete(this);
0204 }
0205 
0206 template <class T>
0207 inline cl_GV_index<T>::operator T () const
0208 {
0209     #ifndef CL_GV_NO_RANGECHECKS
0210     if (!(index < vec->len)) throw runtime_exception();
0211     #endif
0212     return vec->vectorops->element(vec,index);
0213 }
0214 
0215 template <class T>
0216 inline void cl_GV_index<T>::operator= (const T& x) const
0217 {
0218     #ifndef CL_GV_NO_RANGECHECKS
0219     if (!(index < vec->len)) throw runtime_exception();
0220     #endif
0221     vec->vectorops->set_element(vec,index,x);
0222 }
0223 
0224 template <class T>
0225 inline cl_GV_constindex<T>::operator T () const
0226 {
0227     #ifndef CL_GV_NO_RANGECHECKS
0228     if (!(index < vec->len)) throw runtime_exception();
0229     #endif
0230     return vec->vectorops->element(vec,index);
0231 }
0232 
0233 #if (defined(__sparc__) || defined(__mips__) || defined(__mips64__)) && !defined(__GNUC__) // maybe an SGI CC and Sun CC bug? handle "y[j] = x[i];"
0234 template <class T>
0235 inline void cl_GV_index<T>::operator= (const cl_GV_index<T>& x) const
0236 { operator= ((T) x); }
0237 template <class T>
0238 inline void cl_GV_index<T>::operator= (const cl_GV_constindex<T>& x) const
0239 { operator= ((T) x); }
0240 #endif
0241 
0242 
0243 // In memory, a vector looks like this:
0244 
0245 template <class T>
0246 struct cl_heap_GV : cl_heap {
0247     cl_GV_inner<T> v;
0248     // here room for the elements
0249 };
0250 
0251 // And a reference to a vector always looks like this:
0252 
0253 template <class T, class BASE>
0254 struct cl_GV : public BASE {
0255 public:
0256     // Length.
0257     std::size_t size() const
0258     {
0259         return ((const cl_heap_GV<T> *) this->pointer)->v.size();
0260     }
0261     // Reference. Forbid modification of `const cl_GV&' arguments.
0262     const cl_GV_constindex<T> operator[] (unsigned long index) const
0263     {
0264         return ((const cl_heap_GV<T> *) this->pointer)->v[index];
0265     }
0266     const cl_GV_index<T> operator[] (unsigned long index)
0267     {
0268         return ((cl_heap_GV<T> *) this->pointer)->v[index];
0269     }
0270     const cl_GV_constindex<T> operator[] (long index) const
0271     { return operator[]((unsigned long)index); }
0272     const cl_GV_index<T> operator[] (long index)
0273     { return operator[]((unsigned long)index); }
0274     const cl_GV_constindex<T> operator[] (unsigned int index) const
0275     { return operator[]((unsigned long)index); }
0276     const cl_GV_index<T> operator[] (unsigned int index)
0277     { return operator[]((unsigned long)index); }
0278     const cl_GV_constindex<T> operator[] (int index) const
0279     { return operator[]((unsigned long)index); }
0280     const cl_GV_index<T> operator[] (int index)
0281     { return operator[]((unsigned long)index); }
0282     #if long_bitsize < pointer_bitsize
0283     const cl_GV_constindex<T> operator[] (unsigned long long index) const
0284     {
0285         return ((const cl_heap_GV<T> *) this->pointer)->v[index];
0286     }
0287     const cl_GV_index<T> operator[] (unsigned long long index)
0288     {
0289         return ((cl_heap_GV<T> *) this->pointer)->v[index];
0290     }
0291     const cl_GV_constindex<T> operator[] (long long index) const
0292     { return operator[]((unsigned long long)index); }
0293     const cl_GV_index<T> operator[] (long long index)
0294     { return operator[]((unsigned long long)index); }
0295     #endif
0296     // Copy constructor.
0297     cl_GV (const cl_GV&);
0298     // Assignment operator.
0299     cl_GV& operator= (const cl_GV&);
0300     // Copy a piece of a vector into another vector.
0301     // (Both vectors must be of the same type. Overlapping not allowed.)
0302     static void copy_elements (const cl_GV& src, std::size_t srcindex, cl_GV& dest, std::size_t destindex, std::size_t count)
0303     {
0304         const cl_heap_GV<T> * hsrc = (const cl_heap_GV<T> *) src.pointer;
0305         cl_heap_GV<T> * hdest = (cl_heap_GV<T> *) dest.pointer;
0306         if (!(hsrc->v.vectorops == hdest->v.vectorops))
0307             throw runtime_exception();
0308         hsrc->v.vectorops->copy_elements(&hsrc->v,srcindex,&hdest->v,destindex,count);
0309     }
0310     // Private pointer manipulations.
0311     operator cl_heap_GV<T>* () const;
0312     cl_GV (cl_heap_GV<T>* p) : BASE ((cl_private_thing) p) {}
0313     cl_GV (cl_private_thing p) : BASE (p) {}
0314 protected:
0315     // Forbid use of default constructor.
0316     cl_GV ();
0317 };
0318 #define CL_GV(T,BASE) cl_GV<T,BASE>
0319 // Define copy constructor.
0320 template <class T, class BASE>
0321     _CL_DEFINE_COPY_CONSTRUCTOR2(CL_GV(T,BASE),cl_GV,BASE)
0322 // Define assignment operator.
0323 template <class T, class BASE>
0324     CL_DEFINE_ASSIGNMENT_OPERATOR(CL_GV(T,BASE),CL_GV(T,BASE))
0325 // Private pointer manipulations. Never throw away a `struct cl_heap_GV<T> *'!
0326 template <class T, class BASE>
0327 inline CL_GV(T,BASE)::operator cl_heap_GV<T>* () const
0328 {
0329     cl_heap_GV<T>* hpointer = (cl_heap_GV<T>*)this->pointer;
0330     cl_inc_refcount(*this);
0331     return hpointer;
0332 }
0333 #undef CL_GV
0334 
0335 // The "generic" general vector type.
0336 
0337 typedef cl_heap_GV<cl_gcobject> cl_heap_GV_any;
0338 typedef cl_GV<cl_gcobject,cl_V_any> cl_GV_any;
0339 
0340 
0341 // Hack section.
0342 
0343 // Conversions to subtypes without checking:
0344   #define The(type)  *(const type *) & cl_identity
0345 // This inline function is for type checking purposes only.
0346   inline const cl_GV_any& cl_identity (const cl_GV_any& x) { return x; }
0347 
0348 }  // namespace cln
0349 
0350 #endif /* _CL_GV_H */