Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members  

DictConstraints.cxx

Go to the documentation of this file.
00001 // $Header: /nfs/slac/g/glast/ground/cvs/xmlUtil/src/id/DictConstraints.cxx,v 1.7 2002/04/05 18:26:43 jrb Exp $
00002 
00003 #include <string>
00004 #include <algorithm>
00005 #include "xml/Dom.h"
00006 #include "xmlUtil/id/DictConstraints.h"
00007 #include <dom/DOMString.hpp>
00008 #include <dom/DOM_Element.hpp>
00009 #include <dom/DOM_NodeList.hpp>
00010 
00011 
00012 namespace xmlUtil {
00017   DictConstraints::DictConstraints(DOM_Element elt) : 
00018     m_style(ESTYLE_uninit), m_valList(0), m_minVal(0), m_maxVal(0)
00019   {
00020     DOMString vType = elt.getTagName();
00021     if (vType.equals("vEnumVal")) {
00022       DOMString attVal = elt.getAttribute("value");
00023       m_minVal = atoi(xml::Dom::transToChar(attVal));
00024       m_maxVal = m_minVal;
00025       m_style = ESTYLE_single;
00026     }
00027     else if (vType.equals("vMinMax") ) {
00028       DOMString minVal = elt.getAttribute("min");
00029       m_minVal = atoi(xml::Dom::transToChar(minVal));
00030       DOMString maxVal = elt.getAttribute("max");
00031       m_maxVal = atoi(xml::Dom::transToChar(maxVal));
00032       m_style = (m_minVal == m_maxVal) ? ESTYLE_single : ESTYLE_interval;
00033     }
00034     // Probably should revise this to sort the list before storing
00035     // For now, just update min and max correctly
00036     else if (vType.equals("vList")) { 
00037       m_minVal = 0xffffffff;
00038 
00039       DOM_NodeList children = elt.getChildNodes();
00040       unsigned nChild = children.getLength();
00041       if (nChild == 0) {
00042         m_style = ESTYLE_uninit;
00043         return;
00044       }
00045       m_valList = new std::vector<unsigned>(nChild);
00046       for (unsigned ix = 0; ix < nChild; ix++) {
00047         int temp;
00048         DOM_Node    childNode = children.item(ix);
00049         DOM_Element child = static_cast<DOM_Element &>(childNode);
00050         temp =
00051           atoi(xml::Dom::transToChar(child.getAttribute("value")));
00052         if (temp < 0) {
00053           //complain
00054         }
00055         else {
00056           unsigned newVal = temp;
00057           m_valList->push_back(newVal);
00058           if (newVal < m_minVal) m_minVal = newVal;
00059           if (newVal > m_maxVal) m_maxVal = newVal;
00060         }
00061       }
00062       //      if ((m_minVal < 0 ) || (m_maxVal < 0)) {
00063         //complain
00064       //      }
00065       
00066       // Check if it's really an interval after all.  Look for all
00067       // inbetween elements
00068       if (m_valList) {
00069         for (unsigned iy = m_minVal + 1; iy < m_maxVal; iy++) {
00070           // if there is anything we can't find, we really need a list
00071           if (std::find(m_valList->begin(), m_valList->end(), iy) == 
00072               m_valList->end()) {
00073             m_style = ESTYLE_list;
00074             return; 
00075           }
00076         }
00077         // Everything was there.  The bounds are sufficient.
00078         delete m_valList;
00079         m_style = (m_minVal == m_maxVal) ? ESTYLE_single : ESTYLE_interval;
00080         m_valList = 0;
00081       }
00082     }
00083   }
00084 
00085   DictConstraints::DictConstraints(const unsigned soleValue) :
00086     m_style(ESTYLE_single), m_valList(0), m_minVal(soleValue), 
00087     m_maxVal(soleValue) {}
00088 
00089   DictConstraints::DictConstraints(const unsigned min, const unsigned max) :
00090     m_style(ESTYLE_interval), m_valList(0),
00091     m_minVal(min), m_maxVal(max) {}
00092 
00093   DictConstraints::DictConstraints(const DictValList * const list) :
00094     m_style(ESTYLE_list) {
00095     m_valList = new DictValList(*list);
00096     m_minVal = 0xffffffff;
00097     m_maxVal = 0;
00098     for (DictValList::iterator it = (unsigned int *) list->begin(); 
00099          it != list->end(); ++it) {
00100       const unsigned val = *it;
00101       if (val > m_maxVal) m_maxVal = val;
00102       if (val < m_minVal) m_minVal = val;
00103     }
00104   }
00105 
00106   DictConstraints::DictConstraints(const DictConstraints& toCopy) {
00107     deepCopy(toCopy);
00108   }
00109 
00110   void DictConstraints::deepCopy(const DictConstraints& toCopy) {
00111     // Nothing to it unless the DictValList is being used
00112     m_style = toCopy.m_style;
00113     m_valList = 0;
00114     m_minVal = toCopy.m_minVal;
00115     m_maxVal = toCopy.m_maxVal;
00116     if (toCopy.m_valList) {
00117       m_valList = new DictValList(*(toCopy.m_valList));
00118     }
00119   }
00120 
00121 
00122   DictConstraints& DictConstraints::operator=(const DictConstraints& d) {
00123     if (this != &d) {
00124       if (m_valList) delete m_valList;
00125       deepCopy(d);
00126     }
00127     return *this;
00128   }
00129 
00130   bool DictConstraints::equals(const DictConstraints& other) {
00131     if ((m_style != other.m_style) ||
00132         (m_minVal != other.m_minVal) ||
00133         (m_maxVal != other.m_maxVal) ) return false;
00134 
00135     if (m_style == ESTYLE_list) {
00136       return (*m_valList == *(other.m_valList));
00137     }
00138     else return true;
00139   }
00140 
00141   bool DictConstraints::allowed(const unsigned value) const {
00142     switch(m_style) {
00143     case ESTYLE_single: return (value == m_minVal);
00144     case ESTYLE_interval: 
00145       return ((value >= m_minVal) & (value <= m_maxVal));
00146     case ESTYLE_list:
00147       return 
00148         (std::find(m_valList->begin(), m_valList->end(), value) != 
00149          m_valList->end());
00150     default:
00151       
00152       return false;
00153     }
00154     return false;
00155   }
00156   
00157   bool DictConstraints::allowed(DictConstraints *other) const {
00158     return allowed(*other);
00159   }
00160 
00161   bool DictConstraints::allowed(const DictConstraints& other) const {
00162 
00163     bool boundsOk = ((other.m_minVal >= m_minVal) && 
00164                      (other.m_maxVal <= m_maxVal) );
00165     // if this isn't a list, this is all there is to check
00166     if (m_valList == 0) return boundsOk;
00167     // If either has a list of values, bounds must still be ok
00168     if (!(boundsOk)) return false;
00169                                                         
00170     // All that's left to check is case where this has a list
00171     // and  bounds are ok.  Just do the brute force thing and
00172     // check each possible value separately.  This would be horrible
00173     // if both were large enumerated sets, but it's very unlikely
00174     // that large sets will be described as a list rather than as an
00175     // interval
00176 
00177     else if (other.m_valList) {
00178       for (unsigned ix = 0; ix < (other.m_valList)->size(); ix++) {
00179         if (!allowed((*(other.m_valList))[ix])) return false;
00180       }
00181     } 
00182     else {  // other is interval-type constraint
00183       for (unsigned iy = other.m_minVal; iy <= other.m_maxVal; iy++) {
00184         if (!allowed(iy)) return false;
00185       }
00186     }
00187     return true;
00188   }
00189 
00190   bool DictConstraints::disjoint(const DictConstraints& other) const {
00191     if ((other.m_minVal > m_maxVal) ||
00192         (other.m_maxVal < m_minVal))  return true;
00193     // If either is an interval, we'll have an intersection
00194     if ((!m_valList) || (!other.m_valList)) return false;
00195 
00196     // Both are lists.  Check for duplicates one at a time
00197     for (DictValList::iterator it = m_valList->begin(); 
00198          it !=m_valList->end(); ++it) {
00199       unsigned val = *it;
00200       if (other.allowed(val)) return false;
00201     }
00202     return true;
00203   }
00204 
00205   bool DictConstraints::disjoint(DictConstraints *other) const {
00206     return disjoint(*other);
00207   }
00208 
00209   void DictConstraints::insertValues(std::set<unsigned>& aSet) const {
00210     if (m_valList == 0) {
00211       for (unsigned i = m_minVal; i <= m_maxVal; i++) {
00212         aSet.insert(i);
00213       }
00214     }
00215     else {
00216       aSet.insert(m_valList->begin(), m_valList->end());
00217     }
00218     return;
00219   }
00220 
00221 }

Generated on Wed Oct 16 14:02:47 2002 by doxygen1.2.13.1 written by Dimitri van Heesch, © 1997-2001