Inferno  0.2
simple_compare.cpp
Go to the documentation of this file.
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 }