Back to home page

EIC code displayed by LXR

 
 

    


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

0001 // Simple vectors.
0002 
0003 #ifndef _CL_SV_H
0004 #define _CL_SV_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 simple vector has the same operations as a vector, but it can store
0015 // _only_ cl_gcobject's.
0016 // This class is here because the general vectors always need a function
0017 // call for getting/setting the element of a vector. Our main application
0018 // of the general vectors are the bit vectors, needed for implementing
0019 // polynomials over modular integer rings. I don't want that polynomials
0020 // over other rings (in particular cl_I) be penalized by the mere existence
0021 // of polynomials over modular integer rings.
0022 
0023 // When the vectors were implemented like this:
0024 //
0025 //    cl_GV<cl_I>  -->  cl_GV<cl_RA>  -->  cl_GV<cl_R>  -->  cl_GV<cl_N>
0026 //
0027 // a bit/byte-vector (of integers with limited range) could actually be
0028 // treated correctly by all the functions which manipulate vectors of cl_N.
0029 // This is not crucial, however. Here, we'll have disjoint sets
0030 //
0031 //    cl_SV<cl_I>  -->  cl_SV<cl_RA>  -->  cl_SV<cl_R>  -->  cl_SV<cl_N>
0032 //
0033 //    cl_GV<cl_I>
0034 //
0035 // i.e. the functions which manipulate a (simple!) vector of cl_N cannot
0036 // deal with a bit/byte-vector.
0037 // (This is the same issue as UPGRADED-ARRAY-ELEMENT-TYPE in Common Lisp.)
0038 
0039 template <class T> class cl_SV_inner;
0040 
0041 template <class T>
0042 class cl_SV_inner {
0043 protected:
0044     std::size_t len; // number of elements
0045 private:
0046 //  T data[]; // the elements
0047     T * data() { return (T *) (this+1); }
0048     const T * data() const { return (const T *) (this+1); }
0049 public:
0050     std::size_t size() const { return len; } // number of elements
0051     const T & operator[] (unsigned long index) const
0052     {
0053         #ifndef CL_SV_NO_RANGECHECKS
0054         if (!(index < size())) throw runtime_exception();
0055         #endif
0056         return data()[index];
0057     }
0058     T & operator[] (unsigned long index)
0059     {
0060         #ifndef CL_SV_NO_RANGECHECKS
0061         if (!(index < size())) throw runtime_exception();
0062         #endif
0063         return data()[index];
0064     }
0065     // New ANSI C++ compilers also want the following.
0066     const T & operator[] (unsigned int index) const
0067     { return operator[]((unsigned long)index); }
0068     T & operator[] (unsigned int index)
0069     { return operator[]((unsigned long)index); }
0070     const T & operator[] (long index) const
0071     { return operator[]((unsigned long)index); }
0072     T & operator[] (long index)
0073     { return operator[]((unsigned long)index); }
0074     const T & operator[] (int index) const
0075     { return operator[]((unsigned long)index); }
0076     T & operator[] (int index)
0077     { return operator[]((unsigned long)index); }
0078     #if long_bitsize < pointer_bitsize
0079     const T & operator[] (unsigned long long index) const
0080     {
0081         #ifndef CL_SV_NO_RANGECHECKS
0082         if (!(index < size())) throw runtime_exception();
0083         #endif
0084         return data()[index];
0085     }
0086     T & operator[] (unsigned long long index)
0087     {
0088         #ifndef CL_SV_NO_RANGECHECKS
0089         if (!(index < size())) throw runtime_exception();
0090         #endif
0091         return data()[index];
0092     }
0093     const T & operator[] (long long index) const
0094     { return operator[]((unsigned long long)index); }
0095     T & operator[] (long long index)
0096     { return operator[]((unsigned long long)index); }
0097     #endif
0098 public: /* ugh */
0099     // Constructor.
0100     cl_SV_inner (std::size_t l) : len (l) {}
0101 public:
0102     // Destructor.
0103     ~cl_SV_inner ();
0104     // Ability to place an object at a given address.
0105     void* operator new (size_t size, void* ptr) { (void)size; return ptr; }
0106 private:
0107 // No default constructor, copy constructor, assignment operator, new.
0108     cl_SV_inner ();
0109     cl_SV_inner (const cl_SV_inner&);
0110     cl_SV_inner& operator= (const cl_SV_inner&);
0111     void* operator new (size_t size);
0112 };
0113 
0114 // All member functions are inline.
0115 
0116 template <class T>
0117 inline cl_SV_inner<T>::~cl_SV_inner ()
0118 {
0119     std::size_t i = len;
0120     while (i > 0) {
0121         i--;
0122         data()[i].~T();
0123     }
0124 }
0125 
0126 
0127 // In memory, a simple vector looks like this:
0128 
0129 template <class T>
0130 struct cl_heap_SV : cl_heap {
0131     cl_SV_inner<T> v;
0132     // here room for the elements
0133 };
0134 
0135 template <class T, class BASE>
0136 struct cl_SV : public BASE {
0137 public:
0138     // Length.
0139     std::size_t size() const
0140     {
0141         return ((const cl_heap_SV<T> *) this->pointer)->v.size();
0142     }
0143     // Reference. Forbid modification of `const cl_SV&' arguments.
0144     const T & operator[] (unsigned long index) const
0145     {
0146         return ((const cl_heap_SV<T> *) this->pointer)->v[index];
0147     }
0148     T & operator[] (unsigned long index)
0149     {
0150         return ((cl_heap_SV<T> *) this->pointer)->v[index];
0151     }
0152     // New ANSI C++ compilers also want the following.
0153     const T & operator[] (unsigned int index) const
0154     { return operator[]((unsigned long)index); }
0155     T & operator[] (unsigned int index)
0156     { return operator[]((unsigned long)index); }
0157     const T & operator[] (long index) const
0158     { return operator[]((unsigned long)index); }
0159     T & operator[] (long index)
0160     { return operator[]((unsigned long)index); }
0161     const T & operator[] (int index) const
0162     { return operator[]((unsigned long)index); }
0163     T & operator[] (int index)
0164     { return operator[]((unsigned long)index); }
0165     #if long_bitsize < pointer_bitsize
0166     const T & operator[] (unsigned long long index) const
0167     {
0168         return ((const cl_heap_SV<T> *) this->pointer)->v[index];
0169     }
0170     T & operator[] (unsigned long long index)
0171     {
0172         return ((cl_heap_SV<T> *) this->pointer)->v[index];
0173     }
0174     const T & operator[] (long long index) const
0175     { return operator[]((unsigned long long)index); }
0176     T & operator[] (long long index)
0177     { return operator[]((unsigned long long)index); }
0178     #endif
0179     // Constructors.
0180     cl_SV (const cl_SV&);
0181     // Assignment operators.
0182     cl_SV& operator= (const cl_SV&);
0183     // Private pointer manipulations.
0184     cl_SV (cl_heap_SV<T>* p) : BASE ((cl_private_thing)p) {}
0185     cl_SV (cl_private_thing p) : BASE (p) {}
0186 protected:
0187     // Forbid use of default constructor.
0188     cl_SV ();
0189 };
0190 #define CL_SV(T,BASE) cl_SV<T,BASE>
0191 // Define copy constructor.
0192 template <class T, class BASE>
0193     _CL_DEFINE_COPY_CONSTRUCTOR2(CL_SV(T,BASE),cl_SV,BASE)
0194 // Define assignment operator.
0195 template <class T, class BASE>
0196     CL_DEFINE_ASSIGNMENT_OPERATOR(CL_SV(T,BASE),CL_SV(T,BASE))
0197 #undef CL_SV
0198 
0199 // The "generic" simple vector type.
0200 
0201 typedef cl_heap_SV<cl_gcobject> cl_heap_SV_any;
0202 typedef cl_SV<cl_gcobject,cl_V_any> cl_SV_any;
0203 
0204 // Copy a simple vector.
0205 extern const cl_SV_any copy (const cl_SV_any&);
0206 
0207 
0208 // Hack section.
0209 
0210 // Conversions to subtypes without checking:
0211   #define The(type)  *(const type *) & cl_identity
0212 // This inline function is for type checking purposes only.
0213   inline const cl_SV_any& cl_identity (const cl_SV_any& x) { return x; }
0214 
0215 }  // namespace cln
0216 
0217 #endif /* _CL_SV_H */