// File: /workspace/github_cpp_makefile_star2_O2/WShabti-Team[P]WShabtiPict/wshabtilib/api/model.cpp
// Function: pictcore::Model::processExclusions(std::vector<pictcore::Combination*, std::allocator<pictcore::Combination*>>&)
void Model::processExclusions( ComboCollection& vecCombo )
{
    // Sort every parameter's collection of combinations to prepare for set intersection
    for( vector<Parameter*>::iterator ip = m_parameters.begin(); ip != m_parameters.end(); ++ip )
    {
        ( *ip )->SortCombinations();
    }

    for( ExclusionCollection::iterator iexcl = m_exclusions.begin(); iexcl != m_exclusions.end(); ++iexcl )
    {
        // paranoia; shouldn't happen
        assert( !iexcl->empty() );
        if( iexcl->empty() ) continue;

        // form the intersection of the combinations associated with each of the
        //  parameters that make up this exclusion
        ComboCollection intersection;
        Exclusion::iterator iexclterm = iexcl->begin();
        Parameter* sourceParam = iexclterm->first;
        ComboCollection::const_iterator posCandidate = sourceParam->GetCombinationBegin();
        while( true )
        {
            // We're going around and around...
            if( iexcl->end() == ++iexclterm )
            {
                iexclterm = iexcl->begin();
            }

            if( iexclterm->first == sourceParam )
            {
                intersection.push_back( *posCandidate );
                if( ++posCandidate == sourceParam->GetCombinationEnd() ) break;
            }
            // find next >= in this param
            ComboCollection::const_iterator posLB = lower_bound( iexclterm->first->GetCombinationBegin(),
                                                                 iexclterm->first->GetCombinationEnd(),
                                                                 *posCandidate, CombinationPtrSortPred() );
            if( iexclterm->first->GetCombinationEnd() == posLB ) break;
            
            // if >, reset candidate and source
            if( *posLB != *posCandidate )
            {
                posCandidate = posLB;
                sourceParam = iexclterm->first;
            }
        }
        // If the result is empty, make a new combination from the exclusion,
        // mark all of its members satisfied, and make sure all the parameters in the new
        // combination still have sorted combination collections.
        if( intersection.empty() )
        {
            Combination *pNewCombo = new Combination( this );
            int size = 1;
            for( Exclusion::iterator ix = iexcl->begin(); ix != iexcl->end(); ++ix )
            {
                pNewCombo->PushParameter( ( ix->first ) );
                ix->first->LinkCombination( pNewCombo );
                ix->first->SortCombinations();
                size *= ix->first->GetValueCount();
            }
            // Set size of combination's bit vector
            pNewCombo->SetMapSize( size, COVERED );
            vecCombo.push_back( pNewCombo );
            intersection.push_back( pNewCombo );
        }

        for( ComboCollection::iterator ic = intersection.begin(); ic != intersection.end(); ++ic )
        {
            // all exclusions must be applied to the combo and not just the current one
            for( ExclusionCollection::iterator ie = m_exclusions.begin(); ie != m_exclusions.end(); ++ie )
            {
                ( *ic )->ApplyExclusion( const_cast<Exclusion&> ( *ie ) );
            }
        }
    }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x38, %rsp
movq %rsi, 0x30(%rsp)
movq %rdi, %r14
movq 0x8(%rdi), %rbx
cmpq 0x10(%r14), %rbx
je 0xa5c8
movq (%rbx), %rdi
callq 0xc75e
addq $0x8, %rbx
jmp 0xa5b4
movq 0x38(%r14), %rax
leaq 0x28(%r14), %r13
cmpq %r13, %rax
je 0xa752
cmpq $0x0, 0x48(%rax)
je 0xa761
xorps %xmm0, %xmm0
movaps %xmm0, 0x10(%rsp)
andq $0x0, 0x20(%rsp)
movq 0x38(%rax), %rbp
movq 0x20(%rbp), %r15
movq 0x40(%r15), %rbx
movq %rax, 0x8(%rsp)
leaq 0x28(%rax), %r12
movq %rbp, %rdi
callq 0x6500
movq %rax, %rbp
cmpq %rax, %r12
jne 0xa620
movq 0x8(%rsp), %rax
movq 0x38(%rax), %rbp
movq 0x20(%rbp), %rax
cmpq %r15, %rax
jne 0xa644
leaq 0x10(%rsp), %rdi
movq %rbx, %rsi
callq 0xc402
addq $0x8, %rbx
cmpq 0x48(%r15), %rbx
je 0xa66e
movq 0x20(%rbp), %rax
movq 0x40(%rax), %rdi
movq 0x48(%rax), %rsi
movq %rbx, %rdx
callq 0xf70d
movq 0x20(%rbp), %rcx
cmpq %rax, 0x48(%rcx)
je 0xa66e
movq (%rax), %rdx
cmpq (%rbx), %rdx
je 0xa607
movq %rax, %rbx
movq %rcx, %r15
jmp 0xa607
movq 0x10(%rsp), %r15
cmpq 0x18(%rsp), %r15
jne 0xa732
pushq $0x40
popq %rdi
callq 0x6440
movq %rax, %rbp
movq %rax, %rdi
movq %r14, %rsi
callq 0x6fa6
movq 0x8(%rsp), %rax
movq %rbp, (%rsp)
movq 0x38(%rax), %rbp
pushq $0x1
popq %rbx
movq (%rsp), %rdi
cmpq %r12, %rbp
je 0xa6e1
movq 0x20(%rbp), %rsi
callq 0xc436
movq 0x20(%rbp), %rdi
movq (%rsp), %rsi
callq 0xc420
movq 0x20(%rbp), %rdi
callq 0xc75e
movq 0x20(%rbp), %rax
imull 0x38(%rax), %ebx
movq %rbp, %rdi
callq 0x6500
movq %rax, %rbp
jmp 0xa6a4
movl %ebx, %esi
pushq $0x1
popq %rdx
callq 0x6adc
movq 0x30(%rsp), %rdi
movq %rsp, %rsi
callq 0xc402
leaq 0x10(%rsp), %rdi
movq %rsp, %rsi
callq 0xc402
movq 0x10(%rsp), %r15
jmp 0xa732
movq 0x38(%r14), %rbx
cmpq %r13, %rbx
je 0xa72e
movq (%r15), %rdi
leaq 0x20(%rbx), %rsi
callq 0x6ea8
movq %rbx, %rdi
callq 0x6500
movq %rax, %rbx
jmp 0xa710
addq $0x8, %r15
cmpq 0x18(%rsp), %r15
jne 0xa70c
leaq 0x10(%rsp), %rdi
callq 0xd978
movq 0x8(%rsp), %rdi
callq 0x6500
jmp 0xa5d0
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x18129(%rip), %rdi     # 0x22891
leaq 0x17ec6(%rip), %rsi     # 0x22635
leaq 0x1812b(%rip), %rcx     # 0x228a1
movl $0x481, %edx            # imm = 0x481
callq 0x6310
movq %rax, %rbx
pushq $0x40
popq %rsi
movq %rbp, %rdi
callq 0x6460
jmp 0xa79d
jmp 0xa79a
jmp 0xa79a
jmp 0xa79a
jmp 0xa79a
jmp 0xa79a
movq %rax, %rbx
leaq 0x10(%rsp), %rdi
callq 0xd978
movq %rbx, %rdi
callq 0x66e0
nop