aboutsummaryrefslogtreecommitdiff
path: root/src/AMRPlus/flexset.C
diff options
context:
space:
mode:
Diffstat (limited to 'src/AMRPlus/flexset.C')
-rw-r--r--src/AMRPlus/flexset.C215
1 files changed, 215 insertions, 0 deletions
diff --git a/src/AMRPlus/flexset.C b/src/AMRPlus/flexset.C
new file mode 100644
index 0000000..529fb1a
--- /dev/null
+++ b/src/AMRPlus/flexset.C
@@ -0,0 +1,215 @@
+#include "flexset.h"
+
+template <class X>
+void setunion(const flexset<X> &A, const flexset<X> &B,flexset<X> &result){
+ int idxA=0, idxB=0;
+ int sizeA=A.getSize(), sizeB=B.getSize();
+
+ if (A.empty()) {result=B;return;}
+ if (B.empty()) {result=A;return;}
+ result.clear();
+ do {
+ //I dont like to rely on shortcut boolean operators, so
+ //that's why I use double ifs
+
+ X *whichadd=NULL; //1,2,3 (A,B, or both)
+ if (idxA<sizeA && idxB<sizeB){
+ if (A(idxA)<B(idxB)) {
+ whichadd=&A(idxA); idxA++;
+ }
+ else if (B(idxB)<A(idxA)){
+ whichadd=&B(idxB); idxB++;
+ }
+ else {
+ whichadd=A(idxA);
+ idxA++; idxB++;
+ }
+ }
+ else {
+ if (idxA<sizeA){whichadd=&A(idxA); idxA++;}
+ else if (idxB<sizeB){whichadd=&B(idxB); idxB++;}
+ }
+
+ if (whichadd!=NULL)
+ result.append(*whichadd);
+ } while (idxA<sizeA || idxB<sizeB);
+}
+
+template <class X>
+void setunion(flexset<X> &A, const flexset<X> &B){
+ flexset<X> tmp=A;
+ setunion(tmp, B, A);
+}
+
+
+template <class X>
+void setintersection(const flexset<X> &A, const flexset<X> &B,flexset<X> &result){
+ int idxA=0, idxB=0;
+ int sizeA=A.getSize(), sizeB=B.getSize();
+
+ result.clear();
+ if (A.empty() || B.empty()) return; //result={}
+ do {
+ //I dont like to rely on shortcut boolean operators, so
+ //that's why I use double ifs
+
+ X *whichadd=NULL; //1,2,3 (A,B, or both)
+ if (idxA<sizeA && idxB<sizeB){
+ if (A(idxA)<B(idxB)) {
+ idxA++;
+ }
+ else if (B(idxB)<A(idxA)){
+ idxB++;
+ }
+ else {
+ whichadd=&A[idxA];
+ idxA++; idxB++;
+ }
+ }
+ else return; //if we've finished off one set, then no more elts in intersection
+
+ if (whichadd!=NULL)
+ result.append(*whichadd);
+ } while (idxA<sizeA || idxB<sizeB);
+}
+
+
+template <class X>
+void setsymmetricdifference(const flexset<X> &A, const flexset<X> &B,flexset<X> &result){
+ int idxA=0, idxB=0;
+ int sizeA=A.getSize(), sizeB=B.getSize();
+ if (A.empty()) {result.clear(); return;}
+ if (B.empty()) {result=A;return;}
+ result.clear();
+ do {
+ //I dont like to rely on shortcut boolean operators, so
+ //that's why I use double ifs
+
+ X *whichadd=NULL; //1,2,3 (A,B, or both)
+ if (idxA<sizeA && idxB<sizeB){
+ if (A(idxA)<B(idxB)) {
+ whichadd=&A(idxA); idxA++;
+ }
+ else if (B(idxB)<A(idxA)){
+ whichadd=&B(idxB); idxB++;
+ }
+ else {
+ idxA++; idxB++;
+ }
+ }
+ else {
+ if (idxA<sizeA){whichadd=&A(idxA); idxA++;}
+ else if (idxB<sizeB){whichadd=&B(idxB); idxB++;}
+ }
+
+ if (whichadd!=NULL)
+ result.append(*whichadd);
+ } while (idxA<sizeA || idxB<sizeB);
+}
+
+template <class X>
+void setdifference(const flexset<X> &A, const flexset<X> &B,flexset<X> &result){
+ int idxA=0, idxB=0;
+ int sizeA=A.getSize(), sizeB=B.getSize();
+ if (A.empty()) {result=A; return;}
+ if (B.empty()) {result=A;return;}
+ result.clear();
+ do {
+ //I dont like to rely on shortcut boolean operators, so
+ //that's why I use double ifs
+
+ X *whichadd=NULL; //1,2,3 (A,B, or both)
+ if (idxA<sizeA && idxB<sizeB){
+ if (A(idxA)<B(idxB)) {
+ whichadd=&A[idxA]; idxA++;
+ }
+ else if (B(idxB)<A(idxA)){
+ idxB++;
+ }
+ else {
+ idxA++; idxB++;
+ }
+ }
+ else {
+ if (idxA<sizeA){whichadd=&A[idxA]; idxA++;}
+ else if (idxB<sizeB){idxB++;}
+ }
+
+ if (whichadd!=NULL)
+ result.append(*whichadd);
+ } while (idxA<sizeA || idxB<sizeB);
+}
+
+
+template <class X>
+void setdifferences(const flexset<X> &A, const flexset<X> &B,flexset<X> &AMB,flexset<X> &BMA){
+ int idxA=0, idxB=0;
+ int sizeA=A.getSize(), sizeB=B.getSize();
+ if (A.empty()) {AMB.clear();BMA=B; return;}
+ if (B.empty()) {BMA.clear();AMB=A;return;}
+ AMB.clear();
+ BMA.clear();
+ do {
+ X *whichaddA=NULL;
+ X *whichaddB=NULL;
+ if (idxA<sizeA && idxB<sizeB){
+ if (A(idxA)<B(idxB)) {
+ whichaddA=&A[idxA]; idxA++;
+ }
+ else if (B(idxB)<A(idxA)){
+ whichaddB=&B[idxB];idxB++;
+ }
+ else {
+ idxA++; idxB++;
+ }
+ }
+ else {
+ if (idxA<sizeA){whichaddA=&A[idxA]; idxA++;}
+ else if (idxB<sizeB){whichaddB=&B[idxB];idxB++;}
+ }
+
+ if (whichaddA!=NULL)
+ AMB.append(*whichaddA);
+ if (whichaddB!=NULL)
+ BMA.append(*whichaddB);
+ } while (idxA<sizeA || idxB<sizeB);
+}
+
+
+template <class X>
+void setconvert(flexset<X> &A, const flexset<X> &B){
+ int idxA=0, idxB=0;
+ int sizeA=A.getSize(), sizeB=B.getSize();
+ if (A.empty()) {return;}
+ if (B.empty()) {
+ cout<<"SetConvert - UHOH! A is not contained in B!"<<endl;
+ return;}
+ do {
+ //I dont like to rely on shortcut boolean operators, so
+ //that's why I use double ifs
+
+ if (idxA<sizeA && idxB<sizeB){
+ if (A(idxA)<B(idxB)) {
+ cout<<"SetConvert - UHOH! A is not contained in B!"<<endl;
+ A.clear();
+ return;
+ }
+ else if (B(idxB)<A(idxA)){
+ idxB++;
+ }
+ else {
+ (A[idxA])=B(idxB);
+ idxA++; idxB++;
+ }
+ }
+ else {
+ if (idxA<sizeA){
+ cout<<"SetConvert - UHOH! A is not contained in B!"<<endl;
+ A.clear();
+ return;
+ }
+ }
+
+ } while (idxA<sizeA || idxB<sizeB);
+}
+