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

sbacklnk.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 "sbacklnk.hpp"
00022 
00023 IntelibTypeId SExpressionBacklink::
00024 TypeId(&SExpressionCons::TypeId, true);
00025 
00026 SExpressionBacklink::~SExpressionBacklink()
00027 {
00028     if(Cdr().GetPtr() && !Cdr().IsEmptyList()) {
00029         SExpressionBacklink *nextitem = 
00030             Cdr().DynamicCastGetPtr<SExpressionBacklink>();
00031         if(nextitem && nextitem->back == this) 
00032             nextitem->back = 0;
00033     }
00034 }
00035 
00036 SExpression* SExpressionBacklink::Clone() const
00037 {
00038     throw IntelibX_not_implemented();
00039 }
00040 
00041 bool SExpressionBacklink::ConnectBack(const SBacklinkRef &where_to)
00042 {
00043     if(back || !where_to.Cdr().IsEmptyList()) return false;
00044     back = where_to.GetPtr();
00045     back->Cdr() = this;
00046     return true; 
00047 }
00048 
00049 bool SExpressionBacklink::DisconnectBack()
00050 {
00051     if(!back) return false;
00052     back->Cdr() = *PTheEmptyList;
00053     back = 0;
00054     return true;
00055 }
00056 
00057 void SExpressionBacklink::InsertAfter(const SReference &ref)
00058 {
00059     SExpressionBacklink *tmp = 
00060         new SExpressionBacklink(ref, Cdr());
00061     tmp->back = this;
00062     SExpressionBacklink *nextitem = 
00063         Cdr().DynamicCastGetPtr<SExpressionBacklink>();
00064     if(nextitem) nextitem->back = tmp;
00065     Cdr() = SReference(tmp);  // this form takes care about *tmp
00066 }
00067 
00068 bool SExpressionBacklink::RemoveNext()
00069 {
00070     if(Cdr().IsEmptyList()) return false;
00071     
00072     SExpressionBacklink *item_to_remove = 
00073         Cdr().DynamicCastGetPtr<SExpressionBacklink>();
00074 
00075     if(!item_to_remove) { 
00076         // seems to be a dotted list
00077         Cdr() = *PTheEmptyList;
00078     } else {
00079         SExpressionBacklink *next_item = 
00080             item_to_remove->Cdr().DynamicCastGetPtr<SExpressionBacklink>();
00081         if(next_item) next_item->back = this;
00082         
00083         SReference tmp = item_to_remove->Cdr(); 
00084         item_to_remove->Cdr() = *PTheEmptyList;
00085         item_to_remove->back = 0;
00086         Cdr() = tmp;
00087     }
00088     return true;
00089 }
00090 
00091 SBacklinkRef SExpressionBacklink::Prev() const
00092 {
00093     if(back) 
00094         return SBacklinkRef(back);
00095     else
00096         return SBacklinkRef(*PTheEmptyList);
00097 }
00098 
00099 SBacklinkRef SExpressionBacklink::Next() const
00100 {
00101     return Cdr();
00102 }
00103 
00104 
00105 
00106 SBacklinkRef::SBacklinkRef()
00107    : SReference(*PTheEmptyList)
00108 {}
00109 
00110 SBacklinkRef::SBacklinkRef(SExpressionBacklink *ex)
00111    : SReference(ex)
00112 {}
00113 
00114 SBacklinkRef::
00115 SBacklinkRef(const SBacklinkRef &other)
00116    : SReference(other)
00117 {}
00118 
00119 SBacklinkRef::SBacklinkRef(const SReference &other)
00120    : SReference(other)
00121 {
00122     if(other.IsEmptyList()) return;
00123     if(!other.GetPtr() || 
00124        !other->TermType().IsSubtypeOf(SExpressionBacklink::TypeId)
00125       ) 
00126     {
00127         throw IntelibX_not_a_backlink(other);
00128     }
00129 }
00130 
00131 SBacklinkRef::~SBacklinkRef()
00132 {}
00133 
00134 SBacklinkRef& SBacklinkRef::operator=(const SReference &ref)
00135 {
00136     if(!ref.IsEmptyList()) {
00137         if(!ref.GetPtr() || 
00138            !ref->TermType().IsSubtypeOf(SExpressionBacklink::TypeId)
00139           ) 
00140         {
00141             throw IntelibX_not_a_backlink(ref);
00142         }
00143     }
00144     this->SReference::operator=(ref);
00145     return *this;
00146 }
00147 
00148 SExpressionBacklink* SBacklinkRef::GetPtr() const
00149 {
00150     if(IsEmptyList()) return 0; 
00151     return static_cast<SExpressionBacklink*>(SReference::GetPtr());
00152 }
00153 
00154 void SBacklinkRef::InsertAfter(const SReference &r)
00155 {
00156     if(IsEmptyList()) {
00157         (*this) = new SExpressionBacklink(r, *PTheEmptyList);
00158     } else {
00159         (*this)->InsertAfter(r);
00160     }
00161 }
00162 
00163 bool SBacklinkRef::Remove()
00164 {
00165     if(IsEmptyList()) return false;
00166     if(!(*this)->Prev().IsEmptyList()) {
00167         (*this) = (*this)->Prev();
00168         (*this)->RemoveNext();
00169         return true;
00170     }
00171     // no previous elem...
00172     SExpressionBacklink *nextitem = 
00173         (*this)->Cdr().DynamicCastGetPtr<SExpressionBacklink>();
00174     if(!nextitem) {
00175         // no next item as well, or it is a dotted end. just become empty.
00176         (*this) = *PTheEmptyList;
00177         return true; 
00178     }
00179     // there's the next item... we'll advance forwards
00180     SBacklinkRef tmp = *this;
00181     (*this) = nextitem;
00182     nextitem->DisconnectBack();
00183     return true;
00184 }
00185 
00186 SBacklinkRef SBacklinkRef::operator,(const SReference &s)
00187 {
00188     if(IsEmptyList()) {
00189         SExpressionBacklink *tmp = 
00190             new SExpressionBacklink(s, *PTheEmptyList);
00191         (*this) = tmp;
00192         return *this;
00193     }
00194  
00195     SExpressionBacklink *sbl = GetPtr();
00196     SExpressionBacklink *tmp;
00197     while((tmp = sbl->Cdr().DynamicCastGetPtr<SExpressionBacklink>()))
00198     {
00199         sbl = tmp;
00200     }
00201     sbl->InsertAfter(s);
00202     return SBacklinkRef(static_cast<SExpressionBacklink*>
00203                                           (sbl->Cdr().GetPtr()));
00204 }
00205 
00206 SBacklinkRef SBacklinkRef::Begin() const
00207 {
00208     if(IsEmptyList()) return *this;
00209     SBacklinkRef res(*this);
00210     SBacklinkRef prev;
00211     while(!(prev = res->Prev()).IsEmptyList())
00212     {
00213         res = prev;
00214     }
00215     return res;
00216 }
00217 
00218 SBacklinkRef SBacklinkRef::End() const
00219 {
00220     if(IsEmptyList()) return *this;
00221     SBacklinkRef res(*this);
00222     SBacklinkRef next;
00223     while(!(next = res->Next()).IsEmptyList())
00224     {
00225         res = next;
00226     }
00227     return res;
00228 }
00229 
00230 SBacklinkRef& SBacklinkRef::operator++()
00231 {
00232     if(!IsEmptyList()) (*this) = GetPtr()->Cdr();
00233     return *this;
00234 }
00235 
00236 SBacklinkRef& SBacklinkRef::operator--()
00237 {
00238     if(!IsEmptyList()) (*this) = GetPtr()->Prev();
00239     return *this;
00240 }
00241 
00242 SBacklinkRef SBacklinkRef::operator++(int)
00243 {
00244     if(IsEmptyList()) return *this;
00245     SBacklinkRef res(*this);
00246     (*this) = GetPtr()->Cdr();
00247     return res;
00248 }
00249 
00250 SBacklinkRef SBacklinkRef::operator--(int)
00251 {
00252     if(IsEmptyList()) return *this;
00253     SBacklinkRef res(*this);
00254     (*this) = GetPtr()->Prev();
00255     return res;
00256 }
00257 
00258 
00259 
00260 IntelibX_not_a_backlink::
00261 IntelibX_not_a_backlink(SReference a_param) 
00262     : IntelibX("Not a backlinked cons", a_param) {}
00263 

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