in api/deriver.cpp [284:369]
void ExclusionDeriver::DeriveExclusions()
{
// For preview generation we don't invoke the core of the deriver at all
if( m_task->GetGenerationMode() != GenerationMode::Regular ) return;
DOUT( L"Exclusions:\n" );
for( auto & exclusion : m_exclusions )
{
exclusion.Print();
}
DOUT( L"Derivation: Started\n" );
// Add pointers to referencing exclusions to each parameter
// for_each(m_exclusions.begin(), m_exclusions.end(), AddExclusionParamBackPtrs);
for( ExclusionCollection::iterator ie = m_exclusions.begin(); ie != m_exclusions.end(); ++ie )
{
AddExclusionParamBackPtrs( ie );
}
// Initialize the worklist
for( vector<Parameter*>::iterator i = m_parameters.begin(); i != m_parameters.end(); ++i )
{
if( ( *i )->GetExclusionCount() >= ( *i )->GetValueCount() )
{
m_worklist.push_back( &**i );
}
}
while( !m_worklist.empty() )
{
DOUT( L"worklist size: " << static_cast<int>( m_worklist.size() ) << L"\n" );
DOUT( L"excl col size: " << static_cast<int>( m_exclusions.size() ) << L"\n"; )
m_currentParam = m_worklist[ 0 ];
m_worklist.pop_front();
DOUT( L"worklist item: [" << m_currentParam->GetName() << L"]" <<
L", avg excl size: " << m_currentParam->GetAverageExclusionSize() <<
L", num excls: " << m_currentParam->GetExclusionCount() <<
L"\n"; )
// We need buckets to hold the exclusions pertaining to each value
vector<list<Exclusion *> > buckets( m_currentParam->GetValueCount() );
for( ExclIterCollection::iterator ie = m_currentParam->GetExclusions().begin();
ie != m_currentParam->GetExclusions().end();
++ie )
{
// put ref to each exclusion in appropriate value-relative bucket
// find this parameter in the exclusion
Exclusion::iterator iExcl = find_if( ( *ie )->begin(), ( *ie )->end(),
[this](const ExclusionTerm et) {
return et.first == m_currentParam;
} );
// put the exclusion in the right bucket
assert( iExcl != ( *ie )->end() );
Exclusion* pExcl = const_cast<Exclusion*>( &**ie );
buckets.at( iExcl->second ).push_back( pExcl );
}
// if all the buckets have something in them
int n;
for( n = 0; n < m_currentParam->GetValueCount(); ++n )
{
if( buckets[ n ].empty() ) break;
}
// if there was an empty bucket, go to the next entry in the worklist
if( n < m_currentParam->GetValueCount() ) continue;
// recursively build all cover sets, building up exclusion on other params
Exclusion exclImplied;
m_end = buckets.end();
buildExclusion( exclImplied, buckets.begin() );
peformDelete();
}
DOUT( L"Derivation: Finished\n" );
DOUT( L"Exclusions:\n" );
for( auto & exclusion : m_exclusions )
{
exclusion.Print();
}
}