Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

LatticeBase.cxx

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 //
00003 // Package:     Lattice
00004 // Module:      LatticeBase
00005 // 
00006 // Description: Lattice methods (see comments in header)
00007 //
00008 // Implementation: +---------------+
00009 //                 | See LatticeBase.h |
00010 //                 +---------------+
00011 //
00012 // Author:      Jon Thaler
00013 // Created:     Fri July 30, 1999
00014 //
00015 //  Minos Revision History
00016 //  
00017 //  This file has been converted automatically from the corresponding CLEO
00018 //  Lattice code by Nick West on: 14/03/2000 08:38:06
00019 //  
00020 //  It is being used to explore the possibility that a modified Lattice
00021 //  can be used in MINOS.  The main changes are:-
00022 //  
00023 //      1)  The removal Lattice templates classes:-
00024 //  
00025 //           a)  LinkData is dummy
00026 //           b)  Left and Right ID types are void*
00027 //  
00028 //      2)  Conversion of CLEO types and includes to MINOS equivalents
00029 //          e.g.:-
00030 //  
00031 //           a)  DABoolean -> Bool_t
00032 //           b)  report    -> MSG
00033 
00034 //
00035 
00036 //-------------+
00037 // Environment |
00038 //-------------+
00039 
00040 //----------------------+
00041 // system include files |
00042 //----------------------+
00043 #if defined(AMBIGUOUS_STRING_FUNCTIONS_BUG)
00044 #include <string>
00045 #endif             
00046 
00047 #if defined(STL_TEMPLATE_DEFAULT_PARAMS_FIRST_BUG)
00048 #include <vector>
00049 #include <algorithm>
00050 #endif
00051 
00052 //--------------------+
00053 // user include files |
00054 //--------------------+
00055 #include "Lattice/LatticeBase.h"
00056 #include "MessageService/MsgService.h"
00057 CVSID("$Id: LatticeBase.cxx,v 1.2 2000/05/10 10:07:04 west Exp $");
00058 
00059 //-------------+
00060 // STL classes |
00061 //-------------+
00062 #include <vector>
00063 #include <algorithm>
00064 
00065 //-------------------------------+
00066 // constants, enums and typedefs |
00067 //-------------------------------+
00068 const char* const kLLString = "Lattice.LatticeBase";
00069 
00070 //----------------------------+
00071 // constructor and destructor |
00072 //----------------------------+
00073 LatticeBase::
00074 LatticeBase(LatticeTopology i,
00075             LatticeTopology j,
00076             LatticeTopology k,
00077             LatticeTopology l)
00078           : m_LeftNodes (*new LeftNodes),
00079             m_RightNodes(*new RightNodes),
00080             m_Links     (*new Links),
00081             m_VLeftID   (*new VectorLeftID),
00082             m_VRightID  (*new VectorRightID)
00083 {
00084   MSG("Lat",Msg::kDebug) << "In ctor()." << endl;
00085   //--------------------------------------------------+
00086   // Initialize topology.                             |
00087   // The default value of i,j,k,l is 0, but           |
00088   // m_Topology[0] isn't used, so this ought to work. |
00089   //--------------------------------------------------+
00090   for (int index=0;  index < 5;  m_Topology[index++] = false);
00091   m_Topology[i] = true;
00092   m_Topology[j] = true;
00093   m_Topology[k] = true;
00094   m_Topology[l] = true;
00095   MSG("Lat",Msg::kDebug) << "Topology is" << "Sorry, not available yet" << endl;
00096 }
00097 
00098 //-----------------------------------------------------------+
00099 // Destructor                                                |
00100 //  Delete the nodes and links before deleting the pointers. |
00101 //-----------------------------------------------------------+
00102 LatticeBase::
00103 ~LatticeBase()
00104 {
00105   MSG("Lat",Msg::kDebug) << "in Lattice dtor()" << endl;
00106 
00107   for (LeftNodes::iterator i  = m_LeftNodes.begin();
00108                            i != m_LeftNodes.end();  ++i)
00109   {
00110     delete *i;
00111   }
00112   delete &m_LeftNodes;
00113   delete &m_VLeftID;
00114 
00115   for (RightNodes::iterator j  = m_RightNodes.begin();
00116                             j != m_RightNodes.end();  ++j)
00117   {
00118     delete *j;
00119   }
00120   delete &m_RightNodes;
00121   delete &m_VRightID;
00122 
00123   for (LinkItr k = m_Links.begin();  k != m_Links.end();  ++k)
00124   {
00125     delete *k;
00126   }
00127   delete &m_Links;
00128 }
00129 
00130 //------------------+
00131 // member functions |
00132 //------------------+
00133 //---------------------------------+
00134 // connect();                      |
00135 //  Make or modify a Lattice Link. |
00136 //---------------------------------+
00137 //--- connect(id,id,LinkData&) -------------------------------------------
00138 LatticeBase::Link*
00139 LatticeBase::
00140 connect(LeftID leftID, RightID rightID, const LinkData& LinkData)
00141 {
00142   // Point to the nodes having the two IDs.
00143   // If no node exists (pointer=0), make a new node.
00144 
00145   LeftNode*  pLN   = leftNode(leftID);
00146   LeftNode*  lNode = (pLN)? pLN : newLeftNode(leftID);
00147                      
00148   RightNode* pRN   = rightNode(rightID);
00149   RightNode* rNode = (pRN)? pRN : newRightNode(rightID);
00150 
00151   // Make the link if the nodes will still satisfy the topology constraint.
00152   if (checkLNtopo(lNode) && checkRNtopo(rNode))
00153   {
00154     Link* link = new Link(lNode, rNode, LinkData);
00155     m_Links.push_back(link);
00156 
00157     // Update the nodes.
00158     // Can't use data access methods, because they return const.
00159     lNode->m_Links   .push_back(link);
00160     rNode->m_Links   .push_back(link);
00161     lNode->m_VRightID.push_back(rightID);
00162     rNode->m_VLeftID .push_back(leftID);
00163 
00164     return link;
00165   }
00166   
00167   MSG("Lat",Msg::kWarning)
00168     << " connect attempts to violate topology constraint." << endl;
00169   return 0;
00170 }
00171 
00172 //--- connect(id,id) ---------------------------------------------
00173 LatticeBase::Link*
00174 LatticeBase::
00175 connect(LeftID leftID, RightID rightID)
00176 { 
00177   // Point to the nodes having the two IDs.
00178   // If no node exists (pointer=0), make a new node.
00179   LeftNode*  pLN   = leftNode(leftID);
00180   LeftNode*  lNode = (pLN)? pLN : newLeftNode(leftID);
00181                      
00182   RightNode* pRN   = rightNode(rightID);
00183   RightNode* rNode = (pRN)? pRN : newRightNode(rightID);
00184 
00185   // Make the link if the nodes will still satisfy the topology constraint.
00186   if (checkLNtopo(lNode) && checkRNtopo(rNode))
00187   {
00188     Link* link = new Link(lNode, rNode);
00189     m_Links.push_back(link);
00190 
00191     // Update the nodes.
00192     // Can't use data access methods, because they return const.
00193     lNode->m_Links   .push_back(link);
00194     rNode->m_Links   .push_back(link);
00195     lNode->m_VRightID.push_back(rightID);
00196     rNode->m_VLeftID .push_back(leftID);
00197 
00198     return link;
00199   }
00200   
00201   MSG("Lat",Msg::kWarning)
00202     << " connect attempts to violate topology constraint." << endl;
00203   return 0;
00204 }
00205 
00206 //--- connect(id,Link&,id) ---------------------------------------
00207 LatticeBase::Link*
00208 LatticeBase::
00209 connect(LeftID lid, Link& link, RightID rid)
00210 {
00211   VectorLeftID&  ld     = link.m_VLeftID;
00212   VectorRightID& rd     = link.m_VRightID;
00213   LeftNode*      pLeft  = leftNode (lid);
00214   RightNode*     pRight = rightNode(rid);
00215 
00216   // Make the connection if topology constraint is satisfied. 
00217   if (   (    find(ld.begin(),ld.end(),lid) != ld.end()
00218           || (checkLNtopo(pLeft) && checkLLtopo(link)) )
00219       && (    find(rd.begin(),rd.end(),rid) != rd.end()
00220           || (checkRNtopo(pRight)&& checkRLtopo(link)) ) )
00221   {
00222     addLeftNodeToLink (lid, link);
00223     addRightNodeToLink(rid, link);
00224     return &link;
00225   }
00226   else
00227   {
00228     MSG("Lat",Msg::kWarning)
00229       << " connect attempts to violate topology constraint." << endl;
00230     return 0;
00231   }
00232 }
00233 
00234 //--- connect(id,Link*,id) ---------------------------------------
00235 LatticeBase::Link*
00236 LatticeBase::
00237 connect(LeftID lid, Link* pLink, RightID rid)
00238 {
00239   return (0 == pLink) ? connect(lid, rid) : connect(lid, *pLink, rid);
00240 }
00241 
00242 //--- connect(id,Link&) -------------------------------------------
00243 LatticeBase::Link*
00244 LatticeBase::connect(LeftID lid, Link& link)
00245 {
00246   VectorLeftID& ld    = link.m_VLeftID;
00247   LeftNode*     pLeft = leftNode(lid);
00248 
00249   // Make the connection if topology constraint is satisfied.
00250   if (    find(ld.begin(),ld.end(),lid) != ld.end()
00251       || (checkLNtopo(pLeft) && checkLLtopo(link)) )
00252   {
00253     addLeftNodeToLink(lid, link);
00254     return &link;
00255   }
00256   else
00257   {
00258     MSG("Lat",Msg::kWarning)
00259       << " connect attempts to violate topology constraint." << endl;
00260     return 0;
00261   }
00262 }
00263 
00264 //--- connect(Link&,id) ------------------------------------------
00265 LatticeBase::Link*
00266 LatticeBase::connect(Link& link, RightID rid)
00267 {
00268   VectorRightID& rd     = link.m_VRightID;
00269   RightNode*     pRight = rightNode(rid);
00270 
00271 
00272   // Make the connection if topology constraint is satisfied.
00273   if (    find(rd.begin(),rd.end(),rid) != rd.end()
00274       || (checkRNtopo(pRight) && checkRLtopo(link)) )
00275   {
00276     addRightNodeToLink(rid, link);  
00277     return &link;
00278   }
00279   else
00280   {
00281     MSG("Lat",Msg::kWarning)
00282       << " connect attempts to violate topology constraint." << endl;
00283     return 0;
00284   }
00285 }
00286 
00287 //----------------------------------------------------------------+
00288 // removeLink(link) Remove the specified link, deleting its data. |
00289 //----------------------------------------------------------------+
00290 void LatticeBase::removeLink(Link& link)
00291 {
00292   delete &link;
00293 }
00294 
00295 //------------------------------------------------+
00296 // Lattice data.                                  |
00297 //  vLeftID ()                                    |
00298 //  vRightID()                                    |
00299 //  links   ()                                    |
00300 //   Returns the Lattice's identifiers and links. |
00301 //------------------------------------------------+
00302 //--- vLeftID ----------------------------------------------------
00303 const LatticeBase::VectorLeftID&
00304 LatticeBase      ::vLeftID() const
00305 {
00306   return m_VLeftID;
00307 }
00308 
00309 //--- vRightID ---------------------------------------------------
00310 const LatticeBase::VectorRightID&
00311 LatticeBase      ::vRightID() const
00312 {
00313   return m_VRightID;
00314 }
00315 
00316 //--- links ------------------------------------------------------
00317 const LatticeBase::Links&
00318 LatticeBase      ::links() const
00319 {
00320   return m_Links;
00321 }
00322 
00323 //--------------------------------------------------------------+
00324 // Identifier specific data.                                    |
00325 //  Given a datum, retrieve its associated links or other data. |
00326 //--------------------------------------------------------------+
00327 
00328 //---------------------------------------------------------+
00329 // linksGivenLeft (LeftID  or LeftItr)                     |
00330 // linksGivenRight(RightID or RightItr)                    |
00331 //   Returns a pointer to the table of links used by the   |
00332 //   given object.  If the object does not exist, return 0.|
00333 //---------------------------------------------------------+
00334 //--- linksGivenLeft ----------------------------------------------------
00335 const LatticeBase::Links*
00336 LatticeBase::
00337 linksGivenLeft(LeftID leftID) const
00338 {
00339   const LeftNode* pLN = leftNode(leftID);
00340   return (0==pLN) ? 0 : &(pLN->links());
00341 }
00342 
00343 const LatticeBase::Links*
00344 LatticeBase::
00345 linksGivenLeft(LeftItr leftItr) const
00346 {
00347   return linksGivenLeft(*leftItr);
00348 }
00349 
00350 //--- linksGivenRight -----------------------------------------------------
00351 const LatticeBase::Links*
00352 LatticeBase::
00353 linksGivenRight(RightID rID) const
00354 {
00355   const RightNode* pRN = rightNode(rID);
00356   return (0==pRN) ? 0 : &(pRN->links());
00357 }
00358 
00359 const LatticeBase::Links*
00360 LatticeBase::
00361 linksGivenRight(RightItr rightItr) const
00362 {
00363   return linksGivenRight(*rightItr);
00364 }
00365 
00366 //----------------------------------------------------------------+
00367 // linkGivenLeft (LeftID  or LeftItr)                             |
00368 // linkGivenRight(RightID or RightItr)                            |
00369 //  Retrieve one datum's only link.                               |
00370 //  Fails (returns 0) if there is not exactly one link present.   |
00371 // Both const and non-const versions, so user can change LinkData.|
00372 //----------------------------------------------------------------+
00373 //--- linkGivenLeft -----------------------------------------------------
00374 const LatticeBase::Link*
00375 LatticeBase      ::
00376 linkGivenLeft(LeftID leftID) const
00377 {
00378   const LeftNode* pLN = leftNode(leftID);
00379   return ( (0==pLN)  || (1 != pLN->links().size()) )?
00380     0 : pLN->links().front();
00381 }
00382 
00383 LatticeBase::Link*
00384 LatticeBase::
00385 linkGivenLeft(LeftID leftID)
00386 {
00387   const LeftNode* pLN = leftNode(leftID);
00388   return ( (0==pLN)  || (1 != pLN->links().size()) )?
00389     0 : pLN->links().front();
00390 }
00391 
00392 const LatticeBase::Link*
00393 LatticeBase      ::
00394 linkGivenLeft(LeftItr leftItr) const
00395 {
00396   return linkGivenLeft(*leftItr);
00397 }
00398 
00399 LatticeBase::Link*
00400 LatticeBase::
00401 linkGivenLeft(LeftItr leftItr)
00402 {
00403   return linkGivenLeft(*leftItr);
00404 }
00405 
00406 //--- linkGivenRight ------------------------------------------------------
00407 const LatticeBase::Link*
00408 LatticeBase      ::
00409 linkGivenRight(RightID rightID) const
00410 {
00411   const RightNode* pRN = rightNode(rightID);
00412   return ( (0==pRN) || (1 != pRN->links().size()) ) ? 0 : pRN->links().front();
00413 }
00414 
00415 LatticeBase::Link*
00416 LatticeBase::
00417 linkGivenRight(RightID rightID)
00418 {
00419   const RightNode* pRN = rightNode(rightID);
00420   return ( (0==pRN) || (1 != pRN->links().size()) ) ? 0 : pRN->links().front();
00421 }
00422 
00423 const LatticeBase::Link*
00424 LatticeBase      ::
00425 linkGivenRight(RightItr rightItr) const
00426 {
00427   return linkGivenRight(*rightItr);
00428 }
00429 
00430 LatticeBase::Link*
00431 LatticeBase::
00432 linkGivenRight(RightItr rightItr)
00433 {
00434   return linkGivenRight(*rightItr);
00435 }
00436 
00437 //--------------------------------------------------------+
00438 // Go from left to right, left to left, etc.              |
00439 //  vLeftGivenLeft  (LeftID  or LeftItr)                  |
00440 //  vRightGivenRight(RightID or RightItr)                 |
00441 //  vRightGivenLeft (LeftID  or LeftItr)                  |
00442 //  vLeftGivenRight (RightID or RightItr)                 |
00443 //   Returns a pointer to a vector of IDs connected to or |
00444 //   sharing links with a given datum.  If the datum does |
00445 //   not exist, return 0.                                 |
00446 //--------------------------------------------------------+
00447 //--- vLeftGivenLeft --------------------------------------------------------
00448 const LatticeBase::VectorLeftID*
00449 LatticeBase      ::
00450 vLeftGivenLeft(LeftID leftID) const
00451 {
00452   const LeftNode* pLN = leftNode(leftID);
00453   return (0==pLN) ? 0 : &(pLN->m_VLeftID);
00454 }
00455 
00456 const LatticeBase::VectorLeftID*
00457 LatticeBase      ::
00458 vLeftGivenLeft(LeftItr i) const
00459 {
00460   return vLeftGivenLeft(*i);;
00461 }
00462 
00463 //--- vRightGivenRight ------------------------------------------------------
00464 const LatticeBase::VectorRightID*
00465 LatticeBase      ::
00466 vRightGivenRight(RightID rightID) const
00467 {
00468   const RightNode* pRN = rightNode(rightID);
00469   return (0==pRN) ? 0 : &(pRN->m_VRightID);
00470 }
00471 
00472 const LatticeBase::VectorRightID*
00473 LatticeBase      ::
00474 vRightGivenRight(RightItr i) const
00475 {
00476   return vRightGivenRight(*i);
00477 }
00478 
00479 //--- vRightGivenLeft(LeftID) -----------------------------------------------
00480 const LatticeBase::VectorRightID*
00481 LatticeBase      ::
00482 vRightGivenLeft(LeftID leftID) const
00483 {
00484   const LeftNode* pLN = leftNode(leftID);
00485   return (0==pLN) ? 0 : &(pLN->m_VRightID);
00486 }
00487 
00488 const LatticeBase::VectorRightID*
00489 LatticeBase      ::
00490 vRightGivenLeft(LeftItr i) const
00491 {
00492   return vRightGivenLeft(*i);
00493 }
00494 
00495 //--- vLeftGivenRight ------------------------------------------------------
00496 const LatticeBase::VectorLeftID*
00497 LatticeBase      ::
00498 vLeftGivenRight(RightID rightID) const
00499 {
00500   const RightNode* pRN = rightNode(rightID);
00501   return (0==pRN) ? 0 : &(pRN->m_VLeftID);
00502 }
00503 
00504 const LatticeBase::VectorLeftID*
00505 LatticeBase      ::
00506 vLeftGivenRight(RightItr i) const
00507 {
00508   return vLeftGivenRight(*i);
00509 }
00510 
00511 //--------------------------------------------------------------+
00512 // Fill a vector (supplied by the user) that points to the      |
00513 // links that connect one datum to another, or that they share. |
00514 //  connectLinks   (left,  right, Links&) \  Left and right     |
00515 //  shareLinksLeft (left,  left,  Links&)  > can be identifier  |
00516 //  shareLinksRight(right, right, Links&) /  or iterator.       |
00517 //--------------------------------------------------------------+
00518 //--- connectLinks -------------------------------------------------------
00519 void
00520 LatticeBase::
00521 connectLinks(LeftID leftID, RightID rightID , Links& links) const
00522 {
00523   // Get the left node's right data container (rd=0 if leftID is not valid).
00524   const VectorRightID* rd = vRightGivenLeft(leftID);
00525   if(0 != rd)
00526   {
00527     // If rightID is in it, look for the links that make the connection
00528     if (find(rd->begin(), rd->end(), rightID) != rd->end())
00529     {
00530       // Look for rightID in each link's right data container.
00531       // If it's there, put the link in the user provided link container.
00532       const Links* list = linksGivenLeft(leftID);
00533       for (LinkItr i = list->begin();  i != list->end(); ++i)
00534       { const VectorRightID& rd2 = (*i)->vRightID();
00535         if (find(rd2.begin(), rd2.end(), rightID) != rd2.end())
00536         {
00537           links.push_back(*i);
00538         }
00539       }
00540     }
00541   }
00542 }
00543 
00544 void
00545 LatticeBase::
00546 connectLinks(LeftItr li, RightItr ri, Links& links) const
00547 {
00548   connectLinks(*li, *ri, links);
00549 }
00550 
00551 //--- shareLinksLeft ---------------------------------------------------
00552 void
00553 LatticeBase::
00554 shareLinksLeft(LeftID leftID1, LeftID leftID2, Links& links) const
00555 {
00556   // Get the first node's left data container (ld1=0 if leftID1 is not valid).
00557   const VectorLeftID* ld1 = vLeftGivenLeft(leftID1);
00558   if(0 != ld1)
00559   {
00560     // If leftID2 is in it, look for the links that make the connection
00561     if (find(ld1->begin(), ld1->end(), leftID2) != ld1->end())
00562     {
00563       // Look for leftID2 in each link's left data container.
00564       // If it's there, put the link in the user provided link container.
00565       const Links* list = linksGivenLeft(leftID2);
00566       for (LinkItr i = list->begin();  i != list->end(); ++i)
00567       { const VectorLeftID& ld2 = (*i)->vLeftID();
00568         if (find(ld2.begin(), ld2.end(), leftID2) != ld2.end())
00569         {
00570           links.push_back(*i);
00571         }
00572       }
00573     }
00574   }
00575 }
00576 
00577 void
00578 LatticeBase::
00579 shareLinksLeft(LeftItr li1, LeftItr li2, Links& links) const
00580 {
00581   shareLinksLeft(*li1, *li2, links);
00582 }
00583 
00584 //--- shareLinksRight ------------------------------------------------------
00585 void
00586 LatticeBase::
00587 shareLinksRight(RightID rightID1, RightID rightID2, Links& links) const
00588 {
00589   // Get the first node's right data container (rd1=0 if rightID1 not valid).
00590   // If rightID2 is in it, look for the links that make the connection
00591   const VectorRightID* rd1 = vRightGivenRight(rightID1);
00592   if(0 != rd1)
00593   {
00594     if (find(rd1->begin(), rd1->end(), rightID2) != rd1->end())
00595     {
00596       // Look for rightID2 in each link's right data container.
00597       // If it's there, put the link in the user provided link container.
00598       const Links* list = linksGivenRight(rightID2);
00599       for (LinkItr i = list->begin();  i != list->end(); ++i)
00600       { const VectorRightID& rd2 = (*i)->vRightID();
00601         if (find(rd2.begin(), rd2.end(), rightID2) != rd2.end())
00602         {
00603           links.push_back(*i);
00604         }
00605       }
00606     }
00607   }
00608 }
00609 
00610 void
00611 LatticeBase::
00612 shareLinksRight(RightItr ri1, RightItr ri2, Links& links) const
00613 {
00614   shareLinksRight(*ri1, *ri2, links);
00615 }
00616 
00617 //----------------------------------------------------------------+
00618 // Return a pointer to the one link that connects one datum to    |
00619 // another, or that they share.                                   |
00620 //  connectLink   (left, right, Links&)  \  Left and right        |
00621 //  shareLinkLeft (left, left,  Links&)   > can be identifier     |
00622 //  shareLinkRight(left, left,  Links&)  /  or iterator.          |
00623 // Return 0 if there are no links, or more than one.              |
00624 // Both const and non-const versions, so user can change LinkData.|
00625 //----------------------------------------------------------------+
00626 //--- connectLink --------------------------------------------------------
00627 // Code that is shared between const & non-const versions.
00628 const LatticeBase::Link*
00629 LatticeBase      ::
00630 cLshared(LeftID lid, RightID rid) const
00631 {
00632   const Link* pLink = 0;
00633   // Get the left node's right ID container.  Abort if lid is not valid.
00634   const VectorRightID* v1 = vRightGivenLeft(lid);
00635   if(0 == v1)
00636   {
00637     return 0;
00638   }
00639 
00640   // Look for the links that make the connection
00641   if (find(v1->begin(), v1->end(), rid) != v1->end())
00642   {
00643     // Look for rid in each link's right data container.
00644     // The first time it's found, set pLink.
00645     // If it's found a second time, abort (return 0).
00646     const Links* list = linksGivenLeft(lid);
00647     for (LinkItr i = list->begin();  i != list->end(); ++i)
00648     { const VectorRightID& v2 = (*i)->vRightID();
00649       if (find(v2.begin(), v2.end(), rid) != v2.end())
00650       {
00651         if (0 == pLink)
00652         {
00653           pLink = *i;
00654         }
00655         else
00656         {
00657           return 0;
00658         }
00659       }
00660     }
00661   }
00662   return pLink;
00663 }
00664 
00665 const LatticeBase::Link*
00666 LatticeBase      ::
00667 connectLink(LeftID lid, RightID rid) const
00668 {
00669   return cLshared(lid,rid);
00670 }
00671 
00672 LatticeBase::Link*
00673 LatticeBase::
00674 connectLink(LeftID lid, RightID rid)
00675 {
00676   return const_cast<Link*>(cLshared(lid,rid));
00677 }
00678 
00679 const LatticeBase::Link*
00680 LatticeBase      ::
00681 connectLink(LeftItr li, RightItr ri) const
00682 {
00683   return connectLink(*li, *ri);
00684 }
00685 
00686 LatticeBase::Link*
00687 LatticeBase::
00688 connectLink(LeftItr li, RightItr ri)
00689 {
00690   return connectLink(*li, *ri);
00691 }
00692 
00693 //--- shareLinkLeft ----------------------------------------------------------
00694 // Code that is shared between const & non-const versions.
00695 const LatticeBase::Link*
00696 LatticeBase      ::
00697 sLLshared(LeftID id1, LeftID id2) const
00698 {
00699   const Link* pLink = 0;
00700   // Get the first node's left ID container.  Abort if the ID is not valid.
00701   const VectorLeftID* v1 = vLeftGivenLeft(id1);
00702   if(0 == v1)
00703   {
00704     return 0;
00705   }
00706 
00707   // Look for the links that make the connection
00708   if (find(v1->begin(), v1->end(), id2) != v1->end())
00709   {
00710     // Look for id2 in each link's left data container.
00711     // The first time it's found, set pLink.
00712     // If it's found a second time, abort (return 0).
00713     const Links* list = linksGivenLeft(id1);
00714     for (LinkItr i = list->begin();  i != list->end(); ++i)
00715     { const VectorLeftID& v2 = (*i)->vLeftID();
00716       if (find(v2.begin(), v2.end(), id2) != v2.end())
00717       {
00718         if (0 == pLink)
00719         {
00720           pLink = *i;
00721         }
00722         else
00723         {
00724           return 0;
00725         }
00726       }
00727     }
00728   }
00729   return pLink;
00730 }
00731 
00732 const LatticeBase::Link*
00733 LatticeBase      ::
00734 shareLinkLeft(LeftID id1, LeftID id2) const
00735 {
00736   return sLLshared(id1,id2);
00737 }
00738 
00739 LatticeBase::Link*
00740 LatticeBase::
00741 shareLinkLeft(LeftID id1, LeftID id2)
00742 {
00743   return const_cast<Link*>(sLLshared(id1,id2));
00744 }
00745 
00746 const LatticeBase::Link*
00747 LatticeBase::
00748 shareLinkLeft(LeftItr i1, LeftItr i2) const
00749 {
00750   return shareLinkLeft(*i1, *i2);
00751 }
00752 
00753 LatticeBase::Link*
00754 LatticeBase::
00755 shareLinkLeft(LeftItr i1, LeftItr i2)
00756 {
00757   return shareLinkLeft(*i1, *i2);
00758 }
00759 
00760 //--- shareLinkRight ----------------------------------------------------------
00761 // Code that is shared between const & non-const versions.
00762 const LatticeBase::Link*
00763 LatticeBase      ::
00764 sLRshared(RightID id1, RightID id2) const
00765 {
00766   Link* pLink = 0;
00767   // Get the first node's left ID container.  Abort if the ID is not valid.
00768   const VectorRightID* v1 = vRightGivenRight(id1);
00769   if(0 == v1)
00770   {
00771     return 0;
00772   }
00773 
00774   // Look for the links that make the connection
00775   if (find(v1->begin(), v1->end(), id2) != v1->end())
00776   {
00777     // Look for id2 in each link's right data container.
00778     // The first time it's found, set pLink.
00779     // If it's found a second time, abort (return 0).
00780     const Links* list = linksGivenRight(id1);
00781     for (LinkItr i = list->begin();  i != list->end(); ++i)
00782     { const VectorRightID& v2 = (*i)->vRightID();
00783       if (find(v2.begin(), v2.end(), id2) != v2.end())
00784       {
00785         if (0 == pLink)
00786         {
00787           pLink = *i;
00788         }
00789         else
00790         {
00791           return 0;
00792         }
00793       }
00794     }
00795   }
00796   return pLink;
00797 }
00798 
00799 const LatticeBase::Link*
00800 LatticeBase      ::
00801 shareLinkRight(RightID id1, RightID id2) const
00802 {
00803 
00804   return sLRshared(id1,id2);
00805 }
00806 
00807 LatticeBase::Link*
00808 LatticeBase::
00809 shareLinkRight(RightID id1, RightID id2)
00810 {
00811   return const_cast<Link*>(sLRshared(id1,id2));
00812 }
00813 
00814 const LatticeBase::Link*
00815 LatticeBase      ::
00816 shareLinkRight(RightItr i1, RightItr i2) const
00817 {
00818   return shareLinkRight(*i1, *i2);
00819 }
00820 
00821 LatticeBase::Link*
00822 LatticeBase::
00823 shareLinkRight(RightItr i1, RightItr i2)
00824 {
00825   return shareLinkRight(*i1, *i2);
00826 }
00827 
00828 //----------------------------------------------+
00829 // Status information.                          |
00830 //  isEmpty()  True if no links have been made. |
00831 //----------------------------------------------+
00832 Bool_t
00833 LatticeBase::isEmpty() const
00834 {
00835   return 0 == m_Links.size();
00836 } 
00837 
00838 //-------------------------------------------------+
00839 // Lattice topology information:                   |
00840 //  isLNodeMulti(), etc                            |
00841 //   Return a Bool_t, true if the corresponding |
00842 //   topology characteristic is enabled.           |
00843 //  topologyText()                                 |
00844 //   Return a string describing the topology.      |
00845 //-------------------------------------------------+
00846 Bool_t
00847 LatticeBase::isLNodeMulti() const
00848 {
00849   return m_Topology[LNodeMulti];
00850 } 
00851 
00852 //--- isRNodeMulti() -----------------------------------------------
00853 Bool_t
00854 LatticeBase::isRNodeMulti() const
00855 {
00856   return m_Topology[RNodeMulti];
00857 }
00858 
00859 //--- isLLinkMulti() -----------------------------------------------
00860 Bool_t
00861 LatticeBase::isLLinkMulti() const
00862 {
00863   return m_Topology[LLinkMulti];
00864 }
00865 
00866 //--- isRLinkMulti -------------------------------------------------
00867 Bool_t
00868 LatticeBase::isRLinkMulti() const
00869 {
00870   return m_Topology[RLinkMulti];
00871 }
00872 
00873 //--- topologyText() -----------------------------------------------
00874 string
00875 LatticeBase::topologyText() const
00876 {
00877   if ( !(   isLNodeMulti() || isRNodeMulti()
00878          || isLLinkMulti() || isRLinkMulti()) )
00879   {
00880     return " default (single connections only)";
00881   }
00882   else 
00883   {
00884     string s = "";
00885     if (m_Topology[LNodeMulti]) { s += " LNodeMulti";}
00886     if (m_Topology[RNodeMulti]) { s += " RNodeMulti";}
00887     if (m_Topology[LLinkMulti]) { s += " LLinkMulti";}
00888     if (m_Topology[RLinkMulti]) { s += " RLinkMulti";}
00889     return s;
00890   }
00891 }
00892 
00893 //--------------------------+
00894 // show(ostream&)           |
00895 //  Shows Lattice contents. |
00896 //--------------------------+
00897 void
00898 LatticeBase::show(ostream& os) const
00899 {
00900   typedef LatticeBase Lattice;
00901   os << "Lattice has topology " << "Sorry, not available yet"          << endl
00902      << " It contains: " << m_LeftNodes.size()  << " left  data," << endl
00903      << "              " << m_RightNodes.size() << " right data," << endl
00904      << "          and " << m_Links.size()      << " links."      << endl;
00905 
00906   // Display the left nodes.
00907   Lattice::LNodeItr iL    = m_LeftNodes.begin();
00908   Lattice::LNodeItr iLend = m_LeftNodes.end();
00909   for ( ; iL != iLend; ++iL)
00910   {
00911     (*iL)->show(os);
00912   }
00913 
00914   // Display the right nodes.
00915   Lattice::RNodeItr iR    = m_RightNodes.begin();
00916   Lattice::RNodeItr iRend = m_RightNodes.end();
00917   for ( ; iR != iRend; ++iR)
00918   {
00919     (*iR)->show(os);
00920   }
00921 
00922   // Display the links.
00923   Lattice::LinkItr iLink    = links().begin();
00924   Lattice::LinkItr iLinkEnd = links().end();
00925   for ( ; iLink != iLinkEnd; ++iLink)
00926   {
00927     if (0 != *iLink)
00928     {
00929       (*iLink)->show(os);
00930     }
00931   }
00932 }
00933 
00934 //--- showLeft(LeftItr, ostream&) ------------------------------
00935 void
00936 LatticeBase::
00937 showLeft(LeftItr i, ostream& os) const
00938 {
00939   leftNode(*i)->show(os);
00940 }
00941 
00942 //--- showLeft(LeftID, ostream&) ------------------------------
00943 void
00944 LatticeBase::
00945 showLeft(LeftID id, ostream& os) const
00946 {
00947   leftNode(id)->show(os);
00948 }
00949 
00950 //--- showLeft(LeftItr, ostream&) ------------------------------
00951 void
00952 LatticeBase::
00953 showRight(RightItr i, ostream& os) const
00954 {
00955   rightNode(*i)->show(os);
00956 }
00957 
00958 //--- showRight(RightID, ostream&) ------------------------------
00959 void
00960 LatticeBase::
00961 showRight(RightID id, ostream& os) const
00962 {
00963   rightNode(id)->show(os);
00964 }
00965 
00966 //--- showLink(Link*, ostream&) ---------------------------------
00967 void
00968 LatticeBase::
00969 showLink(Link* pLink, ostream& os) const
00970 {
00971   pLink->show(os);
00972 }
00973 
00974 //--- showLink(LinkItr, ostream&) ---------------------------------
00975 void
00976 LatticeBase::
00977 showLink(LinkItr i, ostream& os) const
00978 {
00979   (*i)->show(os);
00980 }
00981 
00982 //------------------------------------------------------+
00983 // Make new nodes:                                      |
00984 //  newLeftNode (LeftID)                                |
00985 //  newRightNode(RightID)                               |
00986 //    Add a new node to the Lattice.  Keep two vectors, |
00987 //    one of identifiers and one of pointers.           |
00988 //    Return ->new node, or 0 if it failed.             |
00989 //    Don't supercede an existing identifier.           |
00990 //------------------------------------------------------+
00991 LatticeBase::LeftNode*
00992 LatticeBase::newLeftNode(LeftID id)
00993 {
00994   LeftNode* pLN(0);
00995   if (find(m_VLeftID.begin(),m_VLeftID.end(),id) == m_VLeftID.end())
00996   {
00997     m_LeftNodes.push_back(pLN = new LeftNode(id));
00998     m_VLeftID  .push_back(id);
00999   }
01000   else
01001   {
01002     MSG("Lat",Msg::kWarning) << "Duplicate left identifier: " << id << endl;
01003   }
01004   return pLN;
01005 }
01006 
01007 //--- newRightNode(id) ---------------------------------------------
01008 LatticeBase::RightNode*
01009 LatticeBase::newRightNode(RightID id)
01010 {
01011   RightNode* pRN(0);
01012   if (find(m_VRightID.begin(),m_VRightID.end(),id) == m_VRightID.end())
01013   {
01014     m_RightNodes.push_back(pRN = new RightNode(id));
01015     m_VRightID  .push_back(id);
01016   }
01017   else
01018   {
01019     MSG("Lat",Msg::kWarning) << "Duplicate right identifier: " << id << endl;
01020   }
01021   return pRN;
01022 }
01023 
01024 //----------------------------------------------+
01025 // Data access aids (protected)                 |
01026 //  leftNode(id), rightNode(id)                 |
01027 //   Given an ID, return a pointer to the node. |
01028 //   If no node exists, return 0.               |
01029 //----------------------------------------------+
01030 LatticeBase::LeftNode*
01031 LatticeBase::leftNode(LeftID leftID) const
01032 {
01033   LeftItr found = find(m_VLeftID.begin(),m_VLeftID.end(),leftID);
01034   if (found != m_VLeftID.end())
01035   {
01036     unsigned int index = found - m_VLeftID.begin();
01037     return m_LeftNodes[index];
01038   }
01039   else
01040   {
01041     return 0;
01042   }
01043 }
01044 
01045 //--- rightNode(id) -----------------------------------------------
01046 LatticeBase::RightNode*
01047 LatticeBase::rightNode(RightID rightID) const
01048 {
01049   RightItr found = find(m_VRightID.begin(),m_VRightID.end(),rightID);
01050   if (found != m_VRightID.end())
01051   {
01052     unsigned int index = found - m_VRightID.begin();
01053     return m_RightNodes[index];
01054   }
01055   else
01056   {
01057     return 0;
01058   }
01059 }
01060 
01061 //---------------------------------------------------------+
01062 // Check topology constraints (private).                   |
01063 //  Return true if node or link can have a new connection. |
01064 //---------------------------------------------------------+
01065 Bool_t
01066 LatticeBase::checkLNtopo(LeftNode* pLN)
01067 {
01068   return m_Topology[LNodeMulti] || (0 == pLN->m_Links.size());
01069 }
01070 
01071 //--- checkRNtopo(RightNode*)---------------------------------------
01072 Bool_t
01073 LatticeBase::
01074 checkRNtopo(RightNode* pRN)
01075 {
01076   return m_Topology[RNodeMulti] || (0 == pRN->m_Links.size());
01077 }
01078 
01079 //--- checkLLtopo(Link&) -------------------------------------------
01080 Bool_t
01081 LatticeBase::checkLLtopo(Link& link)
01082 {
01083   return m_Topology[LLinkMulti] || (0 == link.m_VLeftID.size());
01084 }
01085 
01086 //--- checkRLtopo(Link&) --------------------------------------------
01087 Bool_t
01088 LatticeBase::checkRLtopo(Link& link)
01089 {
01090   return m_Topology[RLinkMulti] || (0 == link.m_VRightID.size());
01091 }
01092 
01093 //------------------------------------------------------------------+
01094 // Add a node to a link:                                            |
01095 // Add the node to the link's left map.                             |
01096 // Add the node to the left or right data of the other linked nodes.|
01097 // Add the other linked nodes to the left or right data of the node.|
01098 // A node does not go into its own left or right data.              |
01099 //  link     The link to be modified.                               |
01100 //  id       Identifier of the node to be added.                    |
01101 //  pThis    Pointer to the node to be added.                       |
01102 //  ld,rd    The link's left and right node identifier vectors.     |
01103 //------------------------------------------------------------------+
01104 void
01105 LatticeBase::
01106 addLeftNodeToLink(LeftID id, Link& link)
01107 {
01108   // If this node is already in the link's left vector, abort.
01109   VectorLeftID& ld = link.m_VLeftID;
01110   if (find(ld.begin(),ld.end(),id) != ld.end())
01111   {
01112     return;
01113   }
01114 
01115   LeftNode* pThis = leftNode(id);
01116   Links& links    = pThis->m_Links;
01117 
01118   // Iterate over the link's left vector.  Update the left node vectors.
01119   // We must test that two nodes aren't already connected by another link.
01120   for (LeftItr iL = ld.begin();  iL != ld.end();  ++iL)
01121   {
01122     VectorLeftID& nv = pThis->m_VLeftID;
01123     if (find(nv.begin(),nv.end(),*iL) == nv.end())
01124     {
01125       leftNode(*iL)->m_VLeftID.push_back(id);
01126       pThis        ->m_VLeftID.push_back(*iL);
01127     }
01128   }
01129 
01130   // Push this node onto the link's left node vector,
01131   // and the link onto the node's link vector.
01132   ld   .push_back(id);
01133   links.push_back(&link);
01134 
01135   // Iterate over the link's right vector.  Update the far node vectors.
01136   // We must test that two nodes aren't already connected by another link.
01137   VectorRightID& rd = link.m_VRightID;
01138   for (RightItr iR = rd.begin();  iR != rd.end();  ++iR)
01139   {
01140     VectorRightID&fv = pThis->m_VRightID;
01141     if (find(fv.begin(),fv.end(),*iR) == fv.end())
01142     {
01143       rightNode(*iR)->m_VLeftID. push_back(id);
01144       pThis         ->m_VRightID.push_back(*iR);
01145     }
01146   }
01147 }
01148 
01149 //--- addRightNodeToLink(id,Link&) -------------------------------
01150 void
01151 LatticeBase::
01152 addRightNodeToLink(RightID id, Link& link)
01153 {
01154   // If this node is already in the link's right vector, abort.
01155   VectorRightID& rd = link.m_VRightID;
01156   if (find(rd.begin(),rd.end(),id) != rd.end())
01157   {
01158     return;
01159   }
01160   
01161   RightNode* pThis = rightNode(id);
01162   Links&     links = pThis->m_Links;
01163 
01164   // Iterate over the link's right vector.  Update the right node vectors.
01165   // We must test that two nodes aren't already connected by another link.
01166   for (RightItr iR = rd.begin();  iR != rd.end(); ++iR)
01167   {
01168     VectorRightID nv = pThis->m_VRightID;
01169     if (find(nv.begin(),nv.end(),*iR) == nv.end())
01170     {
01171       rightNode(*iR)->m_VRightID.push_back(id);
01172       pThis         ->m_VRightID.push_back(*iR);
01173     }
01174   }
01175 
01176   // Push this node onto the link's right node vector,
01177   // and the link onto the node's link vector.
01178   rd   .push_back(id);
01179   links.push_back(&link);
01180 
01181   // Iterate over the link's left vector.  Update the far node vectors.
01182   // We must test that two nodes aren't already connected by another link.
01183   VectorLeftID& ld = link.m_VLeftID;
01184   for (LeftItr iL = ld.begin();  iL != ld.end();  ++iL)
01185   {
01186     VectorLeftID& fv = pThis->m_VLeftID;
01187     if (find(fv.begin(),fv.end(),*iL) == fv.end())
01188     {
01189       leftNode(*iL)->m_VRightID.push_back(id);
01190       pThis        ->m_VLeftID .push_back(*iL);
01191     }
01192   }
01193 }

Generated on Mon Feb 15 11:06:50 2010 for loon by  doxygen 1.3.9.1