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 #if INTELIB_TEXT_REPRESENTATIONS == 1 00018 #include "sstring.hpp" 00019 #endif 00020 00021 #include "sdbllist.hpp" 00022 00023 00024 00025 IntelibTypeId SExpressionDoubleList::TypeId(&SExpression::TypeId, true); 00026 00027 const SBacklinkRef& SExpressionDoubleList::AddToBegin(const SReference &ref) 00028 { 00029 if(!begin.GetPtr()) { 00030 SetTheOnlyItem(ref); 00031 return begin; 00032 } 00033 SExpressionBacklink *tmp = new SExpressionBacklink(ref, *PTheEmptyList); 00034 SBacklinkRef beg = begin; 00035 begin = tmp; // this version takes care 00036 beg->ConnectBack(begin); 00037 return begin; 00038 } 00039 00040 const SBacklinkRef& SExpressionDoubleList::AddToEnd(const SReference &ref) 00041 { 00042 if(!begin.GetPtr()) { 00043 SetTheOnlyItem(ref); 00044 return begin; 00045 } 00046 end->InsertAfter(ref); 00047 end = end->Next(); 00048 return end; 00049 } 00050 00051 void SExpressionDoubleList::Exclude(const SBacklinkRef &from, 00052 const SBacklinkRef &thru) 00053 { 00054 SBacklinkRef left = from->Prev(); 00055 SBacklinkRef right = thru->Next(); 00056 00057 if(!left.IsEmptyList()) 00058 from->DisconnectBack(); 00059 else 00060 begin = right; 00061 if(!right.IsEmptyList()) 00062 right->DisconnectBack(); 00063 else 00064 end = left; 00065 00066 if(!left.IsEmptyList() && ! right.IsEmptyList()) 00067 right->ConnectBack(left); 00068 } 00069 00070 void SExpressionDoubleList::InsertListAfter(const SBacklinkRef &from, 00071 const SBacklinkRef &left, 00072 const SBacklinkRef &right) 00073 { 00074 SBacklinkRef thru; 00075 if(from.IsEmptyList()) thru = begin; else thru = from->Next(); 00076 if(!thru.IsEmptyList()) { 00077 thru->DisconnectBack(); 00078 thru->ConnectBack(right); 00079 } else { 00080 end = right; 00081 } 00082 if(!from.IsEmptyList()) { 00083 left->ConnectBack(from); 00084 } else { 00085 begin = left; 00086 } 00087 } 00088 00089 void SExpressionDoubleList::SetTheOnlyItem(const SReference &ref) 00090 { 00091 begin = new SExpressionBacklink(ref, *PTheEmptyList); 00092 end = begin; 00093 } 00094 00095 #if INTELIB_TEXT_REPRESENTATIONS == 1 00096 SString SExpressionDoubleList::TextRepresentation() const 00097 { 00098 return begin.GetPtr() ? 00099 begin->TextRepresentation() : 00100 SString("()"); 00101 } 00102 #endif 00103 00104 00105 #if 0 00106 SDoubleListRef::SDoubleListRef(const SReference &ref) 00107 { 00108 if(!ref.GetPtr() || 00109 !ref->TermType().IsSubtypeOf(SExpressionDoubleList::TypeId) 00110 ) 00111 { throw IntelibX_not_a_doublelist(ref); } 00112 } 00113 #endif 00114 00115 #if 0 00116 SDoubleListRef& SDoubleListRef::operator=(SExpressionDoubleList *ex) 00117 { this->SReference::operator=(ex); return *this; } 00118 SDoubleListRef& SDoubleListRef::operator=(SExpressionDoubleList &ex) 00119 { this->SReference::operator=(ex); return *this; } 00120 SDoubleListRef& SDoubleListRef::operator=(const SDoubleListRef &other) 00121 { this->SReference::operator=(other); return *this; } 00122 SDoubleListRef& SDoubleListRef::operator=(const SReference &ref) 00123 { this->operator=(SDoubleListRef(ref)); return *this; } 00124 #endif 00125 00126 void SExpressionDoubleList::Iterator::InsertBefore(const SReference& r) 00127 { 00128 if(Exhausted()) { 00129 master->AddToBegin(r); 00130 SetBegin(); 00131 } else if(IsBegin()) { 00132 master->AddToBegin(r); 00133 } else { 00134 (*this)->Prev()->InsertAfter(r); 00135 } 00136 } 00137 00138 void SExpressionDoubleList::Iterator::InsertAfter(const SReference& r) 00139 { 00140 if(Exhausted()) { 00141 master->AddToEnd(r); 00142 SetEnd(); 00143 } else if(IsEnd()) { 00144 master->AddToEnd(r); 00145 } else { 00146 (*this)->InsertAfter(r); 00147 } 00148 } 00149 00150 bool SExpressionDoubleList::Iterator::Remove() 00151 { 00152 if(!GetPtr() || Exhausted()) return false; 00153 bool b = IsBegin(); 00154 bool e = IsEnd(); 00155 SBacklinkRef::Remove(); 00156 if(IsEmptyList()) // no empty lists here please... just unbound 00157 SReference::operator=(SReference()); 00158 if(b) { master->begin = *this; } 00159 if(e) { master->end = *this; } 00160 return true; 00161 } 00162 00164 // Ranges 00165 00166 SDoubleListRef SDoubleListRange::Copy() const 00167 { 00168 SDoubleListRef res(new SExpressionDoubleList); 00169 for(SBacklinkRef tmp = first; 00170 !tmp.IsEmptyList() && tmp.GetPtr() != follow.GetPtr(); 00171 tmp++) 00172 { 00173 res->AddToEnd(tmp->Car()); 00174 } 00175 return res; 00176 } 00177 00178 SDoubleListRange::LeftEndMover::operator SBacklinkRef() const 00179 { 00180 if(master->IsEmpty()) return *PTheEmptyList; 00181 return master->first; 00182 } 00183 00184 SBacklinkRef SDoubleListRange::LeftEndMover::operator++() const 00185 { 00186 if(master->IsEmpty()) (master->follow)++; 00187 return ++(master->first); 00188 } 00189 00190 SBacklinkRef SDoubleListRange::LeftEndMover::operator++(int) const 00191 { 00192 if(master->IsEmpty()) (master->follow)++; 00193 return (master->first)++; 00194 } 00195 00196 SBacklinkRef SDoubleListRange::LeftEndMover::operator--() const 00197 { 00198 if(master->first.IsEmptyList()) 00199 return (master->first = master->master->GetEnd()); 00200 return --(master->first); 00201 } 00202 00203 SBacklinkRef SDoubleListRange::LeftEndMover::operator--(int) const 00204 { 00205 if(master->first.IsEmptyList()) { 00206 master->first = master->master->GetEnd(); 00207 return *PTheEmptyList; 00208 } 00209 return (master->first)--; 00210 } 00211 00212 void SDoubleListRange::LeftEndMover::JumpToFirst() const 00213 { 00214 master->first = master->master->GetBegin(); 00215 } 00216 00217 void SDoubleListRange::LeftEndMover::JumpToLast() const 00218 { 00219 master->first = *PTheEmptyList; 00220 master->follow = *PTheEmptyList; 00221 } 00222 00223 void SDoubleListRange::LeftEndMover::JumpToRightEnd() const 00224 { 00225 master->first = master->follow; 00226 } 00227 00228 SDoubleListRange::RightEndMover::operator SBacklinkRef() const 00229 { 00230 if(master->IsEmpty()) return *PTheEmptyList; 00231 return master->follow; 00232 } 00233 00234 SBacklinkRef SDoubleListRange::RightEndMover::operator++() const 00235 { 00236 return ++(master->follow); 00237 } 00238 00239 SBacklinkRef SDoubleListRange::RightEndMover::operator++(int) const 00240 { 00241 return (master->follow)++; 00242 } 00243 00244 SBacklinkRef SDoubleListRange::RightEndMover::operator--() const 00245 { 00246 if(master->IsEmpty()) master->LeftEnd()--; 00247 if(master->follow.IsEmptyList()) { 00248 return (master->follow = master->master->GetEnd()); 00249 } 00250 return --(master->follow); 00251 } 00252 00253 SBacklinkRef SDoubleListRange::RightEndMover::operator--(int) const 00254 { 00255 if(master->IsEmpty()) master->LeftEnd()--; 00256 if(master->follow.IsEmptyList()) { 00257 master->follow = master->master->GetEnd(); 00258 return *PTheEmptyList; 00259 } 00260 return (master->follow)--; 00261 } 00262 00263 void SDoubleListRange::RightEndMover::JumpToFirst() const 00264 { 00265 master->first = master->master->GetBegin(); 00266 master->follow = master->first; 00267 } 00268 00269 void SDoubleListRange::RightEndMover::JumpToLast() const 00270 { 00271 master->follow = *PTheEmptyList; 00272 } 00273 00274 void SDoubleListRange::RightEndMover::JumpToLeftEnd() const 00275 { 00276 master->follow = master->first; 00277 } 00278 00279 00280 SBacklinkRef SDoubleListRange::GetFirst() const 00281 { 00282 if(IsEmpty()) return *PTheEmptyList; 00283 return first; 00284 } 00285 00286 const SBacklinkRef& SDoubleListRange::GetFollow() const 00287 { 00288 return follow; 00289 } 00290 00291 SBacklinkRef SDoubleListRange::GetLast() const 00292 { 00293 if(IsEmpty()) return *PTheEmptyList; 00294 if(follow.IsEmptyList()) return master->GetEnd(); 00295 return follow->Prev(); 00296 } 00297 00298 00299 00300 IntelibX_not_a_doublelist:: 00301 IntelibX_not_a_doublelist(SReference a_param) 00302 : IntelibX("Not a double list", a_param) {}