/// <summary> /// Parse from another instance of QSI. Used for formatters /// </summary> internal static QSI <T> Parse(QSI <ISetComponent <IAny> > other) { QSI <T> retVal = new QSI <T>(); retVal.NullFlavor = other.NullFlavor.Clone() as CS <NullFlavor>; retVal.ControlActExt = other.ControlActExt; retVal.ControlActRoot = other.ControlActRoot; retVal.Flavor = other.Flavor; retVal.OriginalText = other.OriginalText.Clone() as ED; foreach (ISetComponent <IAny> itm in other) { retVal.Add((ISetComponent <T>)itm); } return(retVal); }
/// <summary> /// Translate to a QSET data internally /// </summary> private QSET <T> TranslateToQSETInternal(SetOperator operation, List <SXCM <T> > collectedTerms, QSET <T> context) { // We need to construct the appropriate structure switch (operation) { case SetOperator.Exclusive: // difference { // QSD must be broken into groups of two int iofs = 0; QSD <T> diffSet = null; if (context == null) // Null, then the minuend is our first term { diffSet = new QSD <T>(collectedTerms[0].TranslateToQSETComponent(), null); iofs = 1; } else // Not, then the current QSET is the minuend { diffSet = new QSD <T>(context, null); } for (int i = iofs; i < collectedTerms.Count; i++) { diffSet.Subtrahend = collectedTerms[i].TranslateToQSETComponent(); if (i + 1 < collectedTerms.Count) // We need to make a new QSD where this is the minuend { diffSet = new QSD <T>(diffSet, null); } } context = diffSet; break; } case SetOperator.Inclusive: // union is pretty easy { QSU <T> unionSet = new QSU <T>(); bool isQssCandidate = true; if (context != null) { isQssCandidate &= (context is QSS <T>) && (context as QSS <T>).Count() == 1; unionSet.Add(context); } foreach (var itm in collectedTerms) { var qsuItem = itm.TranslateToQSETComponent(); isQssCandidate &= (qsuItem is QSS <T>) && (qsuItem as QSS <T>).Count() == 1; unionSet.Add(qsuItem); } // Is the union set composed entirely of QSS instances with one item? if (isQssCandidate) { var qssSet = new QSS <T>(); foreach (var itm in unionSet) { qssSet.Add((itm as QSS <T>).First()); } context = qssSet; } else { context = unionSet; } break; } case SetOperator.Intersect: // intersect, also pretty easy { QSI <T> intersectSet = new QSI <T>(); if (context != null) { intersectSet.Add(context); } foreach (var itm in collectedTerms) { intersectSet.Add(itm.TranslateToQSETComponent()); } context = intersectSet; break; } case SetOperator.PeriodicHull: // periodic hull, same as difference { // QSP must be broken into groups of two int iofs = 0; QSP <T> periodSet = null; if (context == null) // Null, then the minuend is our first term { periodSet = new QSP <T>(collectedTerms[0].TranslateToQSETComponent(), null); iofs = 1; } else // Not, then the current QSET is the minuend { periodSet = new QSP <T>(context, null); } for (int i = iofs; i < collectedTerms.Count; i++) { periodSet.High = collectedTerms[i].TranslateToQSETComponent(); if (i + 1 < collectedTerms.Count) // We need to make a new QSD where this is the minuend { periodSet = new QSP <T>(periodSet, null); } } context = periodSet; break; } case SetOperator.Hull: // convex hull { throw new InvalidOperationException("Cannot represent a HULL value"); } } return(context); }