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

sdbllist.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 #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) {}

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