Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members

svector.cpp

Go to the documentation of this file.
00001 // +-------------------------------------------------------------------------+
00002 // |               I__n__t__e__L__i__b           0.6.10 development          |
00003 // | Copyright (c) Andrey Vikt. Stolyarov <crocodil_AT_croco.net> 2000-2007. |
00004 // |                                                                         |
00005 // | This is free software. The library part is available under              |
00006 // |                               GNU LESSER GENERAL PUBLIC LICENSE v.2.1.  |
00007 // | GNU LGPL v2.1 is found in docs/gnu_gpl2.txt,  or at  http://www.gnu.org |
00008 // |     Please see also docs/readme.txt and visit http://www.intelib.org    |
00009 // |                                                                         |
00010 // | !!! THERE IS NO WARRANTY OF ANY KIND, NEITHER EXPRESSED NOR IMPLIED !!! |
00011 // +-------------------------------------------------------------------------+
00012 
00013 
00014 
00015 
00016 #include "sexpress.hpp"
00017 #include "iexcept.hpp"
00018 #if INTELIB_TEXT_REPRESENTATIONS == 1
00019 #include "sstring.hpp"
00020 #endif
00021 
00022 #include "svector.hpp"
00023 
00024 
00025 IntelibTypeId SExpressionVector::TypeId(&SExpression::TypeId, true);
00026 
00027 
00028 SExpressionVector::SExpressionVector(int n)
00029     : SExpression(TypeId)
00030 {
00031     if(n<=0) {
00032         size = 0;
00033         real_size = -n;
00034         resizeable = true;
00035     } else {
00036         size = n;
00037         real_size = n;
00038         resizeable = false;
00039     }
00040     vector = real_size!=0 ? new SReference[real_size] : 0;
00041 }
00042 
00043 SExpressionVector::
00044 SExpressionVector(const IntelibTypeId &tid, int n)
00045     : SExpression(tid)
00046 {
00047     if(n<=0) {
00048         size = 0;
00049         real_size = -n;
00050         resizeable = true;
00051     } else {
00052         size = n;
00053         real_size = n;
00054         resizeable = false;
00055     }
00056     vector = real_size!=0 ? new SReference[real_size] : 0;
00057 }
00058 
00059 const SReference& SExpressionVector::operator[](unsigned int n) const
00060 {
00061     INTELIB_ASSERT(n<size, IntelibX_vector_out_of_range(SReference(this)));
00062     return vector[n];
00063 }
00064 
00065 SReference& SExpressionVector::operator[](unsigned int n)
00066 {
00067     if(resizeable) {
00068         if(n>=size) Resize(n);
00069     } else {
00070         INTELIB_ASSERT(n<size,IntelibX_vector_out_of_range(SReference(this)));
00071     }
00072     return vector[n];
00073 }
00074 
00075 SExpression* SExpressionVector::Clone() const 
00076 {
00077     SExpressionVector *res = new SExpressionVector(resizeable ? 0 : size);
00078     if(resizeable) 
00079         res->Resize(size);
00080     for(int i=size-1; i>=0; i--) 
00081         res->vector[i] = vector[i].Clone();
00082     return res;
00083 }
00084 
00085 SString SExpressionVector::TextRepresentation() const 
00086 {
00087     // note that resizeable arrays are missing in Common Lisp
00088     // therefore we use CL notation for non-resizeable arrays
00089     // while the notation for resizeables is slightly changed
00090     SString res(resizeable ? "#~(" : "#(");
00091     for(int i=0; i<Size(); i++) {
00092         if(i>0) res += " ";
00093         SExpression *p = (*this)[i].GetPtr();
00094         res += p ? p->TextRepresentation() : "#<UNBOUND>";
00095     }
00096     res += ")";
00097     return res; 
00098 }
00099 
00100 void SExpressionVector::SetSize(unsigned int n)
00101 {
00102     if(n==size) return;
00103     if(n>size) { Resize(n-1); return; }
00104     /* shrink... */
00105     for(unsigned int i=n; i<size; i++) vector[i] = SReference();
00106     size = n; 
00107 }
00108 
00109 void SExpressionVector::Resize(unsigned int n)
00110 {
00111     if(n<size) return;
00112     if(n<real_size) {
00113         size = n+1;
00114         return;
00115     }
00116     unsigned int ns = real_size>0 ? real_size : 4; 
00117     while(ns <= n) ns*=2;
00118     if(!vector) {
00119         vector = new SReference[ns];
00120         real_size = ns;
00121     } else {
00122         SReference *newvector = new SReference[ns];
00123         for(unsigned int i=0; i<size; i++) newvector[i] = vector[i];
00124         delete[] vector;
00125         vector = newvector;
00126         real_size = ns;
00127     }
00128     size = n+1;
00129 }
00130 
00132 
00133 #if 0
00134 SVectorRef::SVectorRef(const SReference& other)
00135     : SReference(other)
00136 {
00137     if(!GetPtr() || 
00138        !(GetPtr()->TermType().IsSubtypeOf(SExpressionVector::TypeId)))
00139     {
00140         throw IntelibX_not_a_vector(other);
00141     }
00142 }
00143 #endif
00144 
00145 
00146 SVectorRef::SVectorRef(SReference& other, int /*fake*/)
00147     : SVectorRefBase(other)
00148 {
00149     if(!GetPtr()) {
00150         (*this) = new SExpressionVector;
00151         other = *this;
00152         return;
00153     } 
00154     if(!(GetPtr()->TermType().IsSubtypeOf(SExpressionVector::TypeId)))
00155     {
00156         throw IntelibX_not_a_vector(other);
00157     }
00158 }
00159 
00161 // SVectorRange
00162 
00163 SVectorRef SVectorRange::Copy(bool resizeable) const   
00164 {
00165     SVectorRef res(resizeable ? 0 : len);
00166     for(int i=0; i<len; i++) res[i] = (*this)[i+idx];
00167     return res;
00168 }
00169 
00170 SVectorRef SVectorRange::Copy() const
00171 {
00172     SVectorRef res((*this)->IsResizeable() ? 0 : len);
00173     for(int i=0; i<len; i++) res[i] = (*this)[i+idx];
00174     return res;
00175 }   
00176 
00177 void SVectorRange::Erase()
00178 {
00179     for(int i=idx; i<(*this)->Size()-len; i++)
00180         (*this)[i] = (*this)[i+len];
00181     (*this)->SetSize((*this)->Size()-len);
00182     len = 0;
00183 }
00184 
00185 void SVectorRange::Replace(const SVectorRange& other)
00186 {
00187     if(len>other.len) {
00188         int delta = len - other.len;
00189         for(int i=idx+len-delta; i<(*this)->Size()-delta; i++)
00190              (*this)[i] = (*this)[i+delta];
00191         (*this)->SetSize((*this)->Size()-delta);
00192     } else 
00193     if(len<other.len) {
00194         int delta = other.len - len;
00195         (*this)->SetSize((*this)->Size()+delta);
00196         for(int i=(*this)->Size()-1; i>=idx+len+delta; i--)
00197              (*this)[i] = (*this)[i-delta];
00198     }
00199     len = other.len;
00200     for(int i=0;  i<len; i++)
00201         (*this)[idx+i] = other[other.idx+i];
00202 }
00203 
00204 
00206 
00207 IntelibX_not_a_vector::
00208 IntelibX_not_a_vector(SReference a_param) 
00209     : IntelibX("Not a vector", a_param) {}
00210 
00211 IntelibX_vector_out_of_range::
00212 IntelibX_vector_out_of_range(SReference a_param) 
00213     : IntelibX("Vector out of range", a_param) {}
00214 

Generated on Tue Dec 18 00:39:46 2007 for InteLib by  doxygen 1.4.1