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