// File: /workspace/github_cpp_makefile_star2_O2/schneebergerlab[P]GameteBinning/asPollinator_1.0.cpp
// Function: find_bed(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, int, bool*, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>>*)
bool find_bed(string poPat, string pmflag, int pollenid, bool* out, vector<string>* bedregions)
{
    /*
      PPuPPMMuMMuuuMMPuuuPuuMuM
      =>
      PPuPP:1:5
           MMuMMuuuMM:6:15
                     PuuuPuu:16:22
                            MuM:23:25
    */
    if(poPat.size()==0) return false; // should never happen
    //
    size_t posp = poPat.find("P");
    size_t posm = poPat.find("M");
    //
    if(posp==std::string::npos && posm==std::string::npos)
    {
        // only "U"
        *out = false;
    }else
    if(posp==std::string::npos && posm!=std::string::npos)
    {
        // only "M"
        std::stringstream ss;
        ss.str("");        
        ss << "M:" << "1:" << poPat.size(); // real position index now
        (*bedregions).push_back(ss.str());
        *out = true;
    }else
    if(posp!=std::string::npos && posm==std::string::npos)
    {
        // only "P"
        std::stringstream ss;
        ss.str("");               
        ss << "P:" << "1:" << poPat.size(); // real position index now
        (*bedregions).push_back(ss.str());      
        *out = true;
    }else
    {    
        // posp!=std::string::npos && posm!=std::string::npos
        // mixture of PMu
        string thisGT            = ""; // starting with P or M?
        size_t thisbegin         = 0;  // 0 based system - this needs to be increased by 1 to get real position index
        size_t thisend           = 0;  // 0 based system - this needs to be increased by 1 to get real position index
        size_t thisend_exclude_u = 0;
        if(posp < posm)
        {
            thisend            = posp;
            thisGT             = "P";
            thisend_exclude_u  = posp;
        }else
        {
            thisend            = posm;
            thisGT             = "M";
            thisend_exclude_u  = posm;
        }
        for(int jj=thisend+1; jj<poPat.size(); jj ++)
        {
            if(poPat.substr(jj, 1).compare("u")==0) 
            {
                thisend           += 1; // extending 
                // reach end of pattern
                if(thisend==poPat.size()-1)
                {
                    // collect current region
                    std::stringstream ss;
                    ss.str("");  
                    ss << thisGT << ":" << thisbegin+1 << ":" << thisend+1; // real position index now        
                    (*bedregions).push_back(ss.str());
                    ss.str().clear();                       
                }
                continue;
            }else
            if(poPat.substr(jj, 1).compare(thisGT)==0)
            {
                thisend           += 1; // extending
                thisend_exclude_u  = jj;
                // reach end of pattern
                if(thisend==poPat.size()-1)
                {
                    // collect current region
                    std::stringstream ss;
                    ss.str("");  
                    ss << thisGT << ":" << thisbegin+1 << ":" << thisend+1; // real position index now        
                    (*bedregions).push_back(ss.str());
                    ss.str().clear();
                }
            }else
            {   // find a switch from thisGT to anotherGT (P->M or M->P)
                // collect current region
                std::stringstream ss;
                ss.str("");
                size_t left_marker_pos = floor((thisend_exclude_u+jj)/2);           // select the middle-left of the ambiguity region
                ss << thisGT << ":" << thisbegin+1 << ":" << left_marker_pos+1;     // real position index now
                (*bedregions).push_back(ss.str());
                ss.str().clear();
                // next region
                if(thisGT.compare("M") == 0) 
                {
                    thisGT = "P";
                }else
                if(thisGT.compare("P") == 0) 
                {
                    thisGT = "M";
                }else ;       
                /* 0-based marker sequence index, left_marker_pos+1 =< jj
                   theoretically, thisbegin is the middle marker position where PuuM or MuuuP happens. 
                      e.g, MuMuuuPuP
                           123456789
                      thisend_exclude_u = 3
                      jj                = 7
                      left_marker_pos = (3+7)/2 = 5 
                      next begin would be left_marker_pos+1 = 6 with new thisend_exclude_u = 6+1
                */
                thisbegin         = left_marker_pos+1;      
                thisend           = jj;
                thisend_exclude_u = jj;
            }
        }
        *out = true;
    }
    //
    return true;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x218, %rsp            # imm = 0x218
movq %r8, 0x30(%rsp)
movq %rcx, 0x60(%rsp)
movq 0x8(%rdi), %rax
testq %rax, %rax
je 0xc9a9
movq %rdi, %r15
movq %rax, 0x58(%rsp)
leaq 0x77c6(%rip), %rsi      # 0x13b82
xorl %edx, %edx
callq 0x3460
movq %rax, %r14
leaq 0x77ce(%rip), %rsi      # 0x13b9b
movq %r15, %rdi
xorl %edx, %edx
callq 0x3460
movq %rax, %rbx
andq %r14, %rax
cmpq $-0x1, %rax
je 0xc48f
cmpq $-0x1, %r14
setne %al
cmpq $-0x1, %rbx
sete %cl
orb %al, %cl
jne 0xc49c
leaq 0x90(%rsp), %rdi
callq 0x31d0
leaq 0x7ab6(%rip), %rsi      # 0x13ec7
leaq 0x10(%rsp), %rdi
leaq 0x38(%rsp), %rdx
callq 0xe174
leaq 0xa8(%rsp), %rbx
leaq 0x10(%rsp), %rsi
movq %rbx, %rdi
callq 0x3340
leaq 0x10(%rsp), %rdi
callq 0x3120
leaq 0xa0(%rsp), %rdi
leaq 0x76f1(%rip), %rsi      # 0x13b3f
callq 0x3260
leaq 0x76e8(%rip), %rsi      # 0x13b42
movq %rax, %rdi
callq 0x3260
movq 0x8(%r15), %rsi
movq %rax, %rdi
callq 0x31b0
leaq 0x10(%rsp), %rdi
movq %rbx, %rsi
callq 0x3380
leaq 0x10(%rsp), %rsi
movq 0x30(%rsp), %rdi
callq 0x10c90
jmp 0xc53f
movq 0x60(%rsp), %rax
movb $0x0, (%rax)
jmp 0xc9a4
cmpq $-0x1, %rbx
setne %al
cmpq $-0x1, %r14
sete %cl
orb %al, %cl
jne 0xc563
leaq 0x90(%rsp), %rdi
callq 0x31d0
leaq 0x7a01(%rip), %rsi      # 0x13ec7
leaq 0x10(%rsp), %rdi
leaq 0x38(%rsp), %rdx
callq 0xe174
leaq 0xa8(%rsp), %rbx
leaq 0x10(%rsp), %rsi
movq %rbx, %rdi
callq 0x3340
leaq 0x10(%rsp), %rdi
callq 0x3120
leaq 0xa0(%rsp), %rdi
leaq 0x7642(%rip), %rsi      # 0x13b45
callq 0x3260
leaq 0x7633(%rip), %rsi      # 0x13b42
movq %rax, %rdi
callq 0x3260
movq 0x8(%r15), %rsi
movq %rax, %rdi
callq 0x31b0
leaq 0x10(%rsp), %rdi
movq %rbx, %rsi
callq 0x3380
leaq 0x10(%rsp), %rsi
movq 0x30(%rsp), %rdi
callq 0x10c90
leaq 0x10(%rsp), %rdi
callq 0x3120
movq 0x60(%rsp), %rax
movb $0x1, (%rax)
leaq 0x90(%rsp), %rdi
callq 0x31f0
jmp 0xc9a4
leaq 0x795d(%rip), %rsi      # 0x13ec7
leaq 0x10(%rsp), %rdi
leaq 0x90(%rsp), %rdx
callq 0xe174
cmpq %rbx, %r14
jae 0xc594
leaq 0x75fa(%rip), %rsi      # 0x13b82
leaq 0x10(%rsp), %rdi
callq 0x3440
jmp 0xc5a8
leaq 0x7600(%rip), %rsi      # 0x13b9b
leaq 0x10(%rsp), %rdi
callq 0x3440
movq %rbx, %r14
xorl %r12d, %r12d
leaq 0x90(%rsp), %r13
movl %r14d, %ebx
incq %r12
movq %r12, 0x68(%rsp)
movq %r14, %rbp
movq %r14, 0x70(%rsp)
addq $0x2, %rbp
incl %ebx
movq %rbp, %r12
movslq %ebx, %r14
cmpq %r14, 0x8(%r15)
jbe 0xc992
movq %r13, %rdi
movq %r15, %rsi
movq %r14, %rdx
pushq $0x1
popq %rcx
callq 0x3290
movq %r13, %rdi
leaq 0x74bc(%rip), %rsi      # 0x13ab3
callq 0x30c0
movl %eax, %ebp
movq %r13, %rdi
callq 0x3120
testl %ebp, %ebp
jne 0xc707
leaq -0x2(%r12), %rax
movq 0x8(%r15), %rcx
addq $-0x2, %rcx
cmpq %rcx, %rax
jne 0xc6fd
movq %r13, %rdi
callq 0x31d0
leaq 0x38(%rsp), %r14
movq %r14, %rdi
leaq 0x788c(%rip), %rsi      # 0x13ec7
leaq 0xf(%rsp), %rdx
callq 0xe174
leaq 0xa8(%rsp), %rdi
movq %r14, %rsi
callq 0x3340
movq %r14, %rdi
callq 0x3120
leaq 0xa0(%rsp), %rdi
leaq 0x10(%rsp), %rsi
callq 0x3240
movq %rax, %rdi
leaq 0x74ca(%rip), %rsi      # 0x13b43
callq 0x3260
movq %rax, %rdi
movq 0x68(%rsp), %rsi
callq 0x31b0
movq %rax, %rdi
leaq 0x74ae(%rip), %rsi      # 0x13b43
callq 0x3260
movq %rax, %rdi
movq %r12, %rsi
callq 0x31b0
leaq 0x38(%rsp), %r14
movq %r14, %rdi
leaq 0xa8(%rsp), %rsi
callq 0x3380
movq 0x30(%rsp), %rdi
movq %r14, %rsi
callq 0x10c90
movq %r14, %rdi
callq 0x3120
movq %r14, %rdi
leaq 0xa8(%rsp), %rsi
callq 0x3380
andq $0x0, 0x40(%rsp)
movq 0x38(%rsp), %rax
movb $0x0, (%rax)
movq %r14, %rdi
callq 0x3120
movq %r13, %rdi
callq 0x31f0
incq %r12
incl %ebx
jmp 0xc5cf
movq %r13, %rdi
movq %r15, %rsi
movq %r14, %rdx
pushq $0x1
popq %rcx
callq 0x3290
movq %r13, %rdi
leaq 0x10(%rsp), %rsi
callq 0x3030
movl %eax, %ebp
movq %r13, %rdi
callq 0x3120
testl %ebp, %ebp
jne 0xc82a
leaq -0x1(%r12), %rbp
movq %r14, 0x70(%rsp)
cmpq %r12, 0x8(%r15)
jne 0xc5c6
movq %r13, %rdi
callq 0x31d0
leaq 0x38(%rsp), %rdi
leaq 0x7768(%rip), %rsi      # 0x13ec7
leaq 0xf(%rsp), %rdx
callq 0xe174
leaq 0xa8(%rsp), %rdi
leaq 0x38(%rsp), %rsi
callq 0x3340
leaq 0x38(%rsp), %rdi
callq 0x3120
leaq 0xa0(%rsp), %rdi
leaq 0x10(%rsp), %rsi
callq 0x3240
movq %rax, %rdi
leaq 0x73a2(%rip), %rsi      # 0x13b43
callq 0x3260
movq %rax, %rdi
movq 0x68(%rsp), %rsi
callq 0x31b0
movq %rax, %rdi
leaq 0x7386(%rip), %rsi      # 0x13b43
callq 0x3260
movq %rax, %rdi
movq %r12, %rsi
callq 0x31b0
leaq 0x38(%rsp), %r12
movq %r12, %rdi
leaq 0xa8(%rsp), %rsi
callq 0x3380
movq 0x30(%rsp), %rdi
movq %r12, %rsi
callq 0x10c90
movq %r12, %rdi
callq 0x3120
movq %r12, %rdi
leaq 0xa8(%rsp), %rsi
callq 0x3380
andq $0x0, 0x40(%rsp)
movq 0x38(%rsp), %rax
movb $0x0, (%rax)
movq %r12, %rdi
callq 0x3120
movq %r13, %rdi
callq 0x31f0
jmp 0xc5c1
movq %r13, %rdi
callq 0x31d0
leaq 0x38(%rsp), %r12
movq %r12, %rdi
leaq 0x7686(%rip), %rsi      # 0x13ec7
leaq 0xf(%rsp), %rdx
callq 0xe174
leaq 0xa8(%rsp), %rdi
movq %r12, %rsi
callq 0x3340
movq %r12, %rdi
callq 0x3120
movq 0x70(%rsp), %rax
addq %r14, %rax
shrq %rax
cvtsi2sd %rax, %xmm0
movapd %xmm0, 0x80(%rsp)
subsd 0x6834(%rip), %xmm0     # 0x130b8
movapd %xmm0, 0x70(%rsp)
leaq 0xa0(%rsp), %rdi
leaq 0x10(%rsp), %rsi
callq 0x3240
movq %rax, %rdi
leaq 0x729d(%rip), %rsi      # 0x13b43
callq 0x3260
movq %rax, %rdi
movq 0x68(%rsp), %rsi
callq 0x31b0
movq %rax, %rdi
leaq 0x7281(%rip), %rsi      # 0x13b43
callq 0x3260
cvttsd2si 0x80(%rsp), %rcx
movq %rcx, %rdx
cvttsd2si 0x70(%rsp), %rsi
sarq $0x3f, %rdx
andq %rdx, %rsi
orq %rcx, %rsi
incq %rsi
movq %rax, %rdi
movq %rsi, %r12
callq 0x31b0
leaq 0x38(%rsp), %rbp
movq %rbp, %rdi
leaq 0xa8(%rsp), %rsi
callq 0x3380
movq 0x30(%rsp), %rdi
movq %rbp, %rsi
callq 0x10c90
movq %rbp, %rdi
callq 0x3120
movq %rbp, %rdi
leaq 0xa8(%rsp), %rsi
callq 0x3380
andq $0x0, 0x40(%rsp)
movq 0x38(%rsp), %rax
movb $0x0, (%rax)
movq %rbp, %rdi
callq 0x3120
leaq 0x10(%rsp), %rdi
leaq 0x724c(%rip), %rsi      # 0x13b9b
callq 0x30c0
leaq 0x7227(%rip), %rsi      # 0x13b82
testl %eax, %eax
je 0xc97b
leaq 0x10(%rsp), %rdi
leaq 0x7217(%rip), %rsi      # 0x13b82
callq 0x30c0
leaq 0x7224(%rip), %rsi      # 0x13b9b
testl %eax, %eax
jne 0xc985
leaq 0x10(%rsp), %rdi
callq 0x3440
movq %r13, %rdi
callq 0x31f0
jmp 0xc5b6
movq 0x60(%rsp), %rax
movb $0x1, (%rax)
leaq 0x10(%rsp), %rdi
callq 0x3120
movq 0x58(%rsp), %rax
testq %rax, %rax
setne %al
addq $0x218, %rsp            # imm = 0x218
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0xca4d
jmp 0xca4d
jmp 0xca48
jmp 0xca37
jmp 0xca4d
jmp 0xca37
jmp 0xca4d
jmp 0xca48
jmp 0xca4d
jmp 0xca4d
jmp 0xca4d
jmp 0xca37
jmp 0xca37
jmp 0xca48
movq %rax, %rbx
leaq 0x90(%rsp), %rdi
callq 0x3120
jmp 0xca5d
jmp 0xca08
jmp 0xca1d
jmp 0xca48
jmp 0xca08
movq %rax, %rbx
jmp 0xca67
jmp 0xca1d
jmp 0xca08
jmp 0xca1d
movq %rax, %rbx
leaq 0x10(%rsp), %rdi
callq 0x3120
jmp 0xca20
jmp 0xca1d
jmp 0xca4d
jmp 0xca1d
movq %rax, %rbx
leaq 0x90(%rsp), %rdi
callq 0x31f0
jmp 0xca67
jmp 0xca48
jmp 0xca37
jmp 0xca4d
jmp 0xca4d
movq %rax, %rbx
leaq 0x38(%rsp), %rdi
callq 0x3120
jmp 0xca50
jmp 0xca4d
movq %rax, %rbx
jmp 0xca5d
movq %rax, %rbx
leaq 0x90(%rsp), %rdi
callq 0x31f0
leaq 0x10(%rsp), %rdi
callq 0x3120
movq %rbx, %rdi
callq 0x3410