Inferno
0.2
|
00001 #include "simple_compare.hpp" 00002 00003 bool SimpleCompare::operator()( TreePtr<Node> x, TreePtr<Node> y ) 00004 { 00005 // Local comparison deals with node type (or any overloaded matching rule) 00006 // Try both ways to explicitly disallow wildcarding (this fn guaranteed symmetrical) 00007 if( !x->IsLocalMatch(y.get()) || !y->IsLocalMatch(x.get())) 00008 return false; 00009 00010 // Itemise them both and chuck out if sizes do not match 00011 vector< Itemiser::Element * > x_memb = x->Itemise(); 00012 vector< Itemiser::Element * > y_memb = y->Itemise(); 00013 if( x_memb.size() != y_memb.size() ) 00014 return false; 00015 00016 for( int i=0; i<x_memb.size(); i++ ) 00017 { 00018 bool r; 00019 ASSERT( y_memb[i] )( "itemise returned null element"); 00020 ASSERT( x_memb[i] )( "itemise returned null element"); 00021 00022 if( SequenceInterface *x_seq = dynamic_cast<SequenceInterface *>(x_memb[i]) ) 00023 { 00024 SequenceInterface *y_seq = dynamic_cast<SequenceInterface *>(y_memb[i]); 00025 if( !y_seq ) 00026 return false; 00027 if( !operator()( *x_seq, *y_seq ) ) 00028 return false; 00029 } 00030 else if( CollectionInterface *x_col = dynamic_cast<CollectionInterface *>(x_memb[i]) ) 00031 { 00032 CollectionInterface *y_col = dynamic_cast<CollectionInterface *>(y_memb[i]); 00033 if( !y_col ) 00034 return false; 00035 if( !operator()( *x_col, *y_col ) ) 00036 return false; 00037 } 00038 else if( TreePtrInterface *x_ptr = dynamic_cast<TreePtrInterface *>(x_memb[i]) ) 00039 { 00040 TreePtrInterface *y_ptr = dynamic_cast<TreePtrInterface *>(y_memb[i]); 00041 if( !y_ptr ) 00042 return false; 00043 if( !operator()( *x_ptr, *y_ptr ) ) 00044 return false; 00045 } 00046 else 00047 { 00048 ASSERTFAIL("got something from itemise that isnt a Sequence, Collection or a TreePtr"); 00049 } 00050 } 00051 00052 // survived to the end? then we have a match. 00053 return true; 00054 } 00055 00056 00057 bool SimpleCompare::operator()( SequenceInterface &x, SequenceInterface &y ) 00058 { 00059 // Ensure the sizes are the same so we don;t go off the end 00060 if( x.size() != y.size() ) 00061 return false; 00062 00063 ContainerInterface::iterator xit, yit; 00064 00065 // Check each element in turn 00066 for( xit = x.begin(), yit = y.begin(); xit != x.end(); ++xit, ++yit ) 00067 { 00068 if( !operator()( *xit, *yit ) ) 00069 return false; 00070 } 00071 00072 // survived to the end? then we have a match. 00073 return true; 00074 } 00075 00076 00077 bool SimpleCompare::operator()( CollectionInterface &x, CollectionInterface &y ) 00078 { 00079 // Ensure the sizes are the same so we don;t go off the end 00080 if( x.size() != y.size() ) 00081 return false; 00082 00083 Collection<Node> xremaining; 00084 FOREACH( const TreePtrInterface &xe, x ) 00085 xremaining.insert( xe ); 00086 00087 ContainerInterface::iterator xit, yit; 00088 FOREACH( const TreePtrInterface &ye, y ) 00089 { 00090 bool found = false; 00091 TreePtr<Node> xfound; 00092 FOREACH( const TreePtrInterface &xe, xremaining ) 00093 { 00094 if( operator()( xe, ye ) ) 00095 { 00096 found = true; 00097 xfound = xe; 00098 break; 00099 } 00100 } 00101 if( !found ) 00102 return false; 00103 00104 // Try to erase the element 00105 int ner = xremaining.erase( xfound ); 00106 ASSERT( ner == 1 )("Erase erased %d elements, huh?\n", ner ); 00107 } 00108 00109 // survived to the end? then we have a match. 00110 return true; 00111 }