B
     \                 @   s  d Z ddlmZmZmZ ddlZddlZddlZddlZddl	m
Z
 ddlmZmZmZ ddlmZmZmZmZmZmZmZmZ ddlmZ dd	lmZmZ d
d Zdd ZdZdZ dZ!dZ"dZ#dZ$dd Z%dd Z&dd Z'dd Z(e)ddZ*G dd de+Z,G d d! d!e+Z-G d"d# d#e+Z.d$d% Z/ee0d&d' Z1ee0ej2d(d) Z3ee4ej5d*d+ Z6eej7ej5ej8d,d- Z9ed.ej5d/d0 Z:ed1ej;ed2d3 Z<ed4ej5ej8d5d6 Z=ed7ej5ej8d8d9 Z>ed:ej5d;d< Z?ed=ej5ej8d>d? Z@ed@ej5dAdB ZAedCej5dDdE ZBedFej5ej2dGdH ZCedIej5ej5dJdK ZDedLej5ej5dMdN ZEedOej5ej2dPdQ ZFxNejGeDfejHeFfejIeCfejJeEfgD ]&\ZKZLeeKej5ej5eLfdRdSZMqW eejNej5ej5edTej5ej5dUdV ZOeejPej5ej5edWej5ej5dXdY ZQeejRej5ej5edZej5ej5d[d\ ZSeejTej5ej5ed]ej5ej5d^d_ ZUed`ej5ej5dadb ZVeejWej5ej5edcej5ej5ddde ZXeejYej5ej5edfej5ej5dgdh ZZeej[ej5ej5didb ZVeej\ej5ej5djdk Z]eej^ej5ej5dldm Z_eej`ej5ej5dndo Zaeejbej5ej5dpdq Zceej5ej5drds ZddS )tz&
Support for native homogeneous sets.
    )print_functionabsolute_importdivisionN)ir)typescgutilstyping)lower_builtin
lower_castiternext_implimpl_ret_borrowedimpl_ret_new_refimpl_ret_untrackedfor_itercall_len)cached_property   )	quicksortslicingc             C   s4   t |}| | }|||}| j|||dS )zx
    Given a set value and type, get its payload structure (as a
    reference, so that mutations are seen by all).
    )ref)r   
SetPayloadget_data_typeZ
as_pointerZbitcastmake_data_helper)contextbuilderset_typeptrpayload_typeZptrtypayload r   3lib/python3.7/site-packages/numba/targets/setobj.pyget_payload_struct   s    
r!   c             C   s   |  t|}| |S )z7
    Return the entry size for the given set type.
    )r   r   SetEntryget_abi_sizeof)r   r   Zlltyr   r   r    get_entry_size!   s    r$   i      Fc             C   s`   | j }|t}|||fi }| ||}|||f}t| ||}	t|jt	}
|
|	||
S )z.
    Compute the hash of the given value.
    )Ztyping_contextZresolve_value_typehashZget_call_typeget_functionis_hash_usedr   ConstanttypeFALLBACKselect)r   r   typvalueZ	typingctxfntysigfnhis_okZfallbackr   r   r    get_hash_value9   s    
r7   c             C   s   t |jt}|d||S )z8
    Whether the hash value denotes an empty entry.
    z==)r   r,   r-   EMPTYicmp_unsigned)r   r   r5   emptyr   r   r    is_hash_emptyG   s    r;   c             C   s   t |jt}|d||S )z9
    Whether the hash value denotes a deleted entry.
    z==)r   r,   r-   DELETEDr9   )r   r   r5   deletedr   r   r    is_hash_deletedN   s    r>   c             C   s   t |jt}|d||S )z9
    Whether the hash value denotes an active entry.
    <)r   r,   r-   r<   r9   )r   r   r5   r=   r   r   r    r+   U   s    r+   SetLoop)indexentrydo_breakc               @   s   e Zd Zdd Zedd Zejdd Zedd Zejdd Zed	d
 Zejdd
 Zedd Z	e	jdd Z	edd Z
e
jdd Z
edd Zedd Zdd Zd ddZejd!ddZejdd ZdS )"_SetPayloadc             C   s<   t ||||}|| _|| _|| _|| _|d| _|| _d S )Nentries)r!   _context_builder_ty_payloadZ_get_ptr_by_name_entries_ptr)selfr   r   r   r   r   r   r   r    __init__c   s    z_SetPayload.__init__c             C   s   | j jS )N)rI   mask)rL   r   r   r    rN   l   s    z_SetPayload.maskc             C   s   || j _d S )N)rI   rN   )rL   r1   r   r   r    rN   p   s    c             C   s   | j jS )N)rI   used)rL   r   r   r    rO   u   s    z_SetPayload.usedc             C   s   || j _d S )N)rI   rO   )rL   r1   r   r   r    rO   y   s    c             C   s   | j jS )N)rI   fill)rL   r   r   r    rP   }   s    z_SetPayload.fillc             C   s   || j _d S )N)rI   rP   )rL   r1   r   r   r    rP      s    c             C   s   | j jS )N)rI   finger)rL   r   r   r    rQ      s    z_SetPayload.fingerc             C   s   || j _d S )N)rI   rQ   )rL   r1   r   r   r    rQ      s    c             C   s   | j jS )N)rI   dirty)rL   r   r   r    rR      s    z_SetPayload.dirtyc             C   s   || j _d S )N)rI   rR   )rL   r1   r   r   r    rR      s    c             C   s   | j S )z>
        A pointer to the start of the entries array.
        )rJ   )rL   r   r   r    rE      s    z_SetPayload.entriesc             C   s   | j S )zC
        A pointer to the start of the NRT-allocated area.
        )rK   )rL   r   r   r    r      s    z_SetPayload.ptrc             C   s2   t | j| j|}| jj| jt| j|d}|S )z)
        Get entry number *idx*.
        )r   )	r   geprG   rJ   rF   r   r   r"   rH   )rL   idxZ	entry_ptrrB   r   r   r    	get_entry   s
    

z_SetPayload.get_entryFc                s  
j 
jj}
j}
jj}tjt	
tj||t|d}t|d}t}	t|}
r|dtd}d dd} 	
fdd	}tt|t< |
}|| ||}||}||
 W d
Q R X | |x |
}|| |	}||}|||}|||}||
 ||	 | W d
Q R X N r|
}}d|||}||
 | W d
Q R X   | W d
Q R X | t dd}|!tj"  |!tj# ||
fS )ag  
        Lookup the *item* with the given hash values in the entries.

        Return a (found, entry index) tuple:
        - If found is true, <entry index> points to the entry containing
          the item.
        - If found is false, <entry index> points to the empty entry that
          the item can be written to (only if *for_insert* is true)
        r      r%   zlookup.bodyzlookup.foundzlookup.not_foundz
lookup.endc          
      s   
 | }|j}d|6 	|jf}|   W dQ R X W dQ R X t|  W dQ R X r؈t|4 }	d|| |}
| W dQ R X dS )zO
            Check entry *i* against the value being searched for.
            z==N)rU   r)   if_thenr9   keybranchr;   r>   loadr/   store)irB   Z
entry_hasheqj)bb_foundbb_not_foundr   r   eqfn
for_insert
free_indexfree_index_sentinelr5   itemrL   r   r    check_entry   s    

z(_SetPayload._lookup.<locals>.check_entryNz==found)$rF   rG   r-   rN   rH   dtyper*   operatorr]   r   Z	signaturer   Zbooleanr   r,   r   alloca_once_valueand_append_basic_block	for_rangeLINEAR_PROBESrZ   addr[   rY   
goto_blocklshrmulr/   r9   position_at_endZphiZIntTypeZadd_incomingtrue_bit	false_bit)rL   re   r5   rb   intp_trN   rh   oneZfiveZperturbrA   bb_bodybb_endrf   r\   pr^   rg   r   )r_   r`   r   r   ra   rb   rc   rd   r5   re   rL   r    _lookup   sh    





 






z_SetPayload._lookupNc          
   c   s   | j }| j}|tj}t|d}|| j|}t	j
|||dN}| |j}t|||j}	||	 t|j||jd}
|
V  W dQ R X W dQ R X dS )zG
        Iterate over the payload's entries.  Yield a SetLoop.
        r   )start)rA   rB   rC   N)rF   rG   get_value_typer   intpr   r,   ro   rN   r   rm   rU   rA   r+   r)   rW   r@   rC   )rL   r|   r   r   rv   rw   sizeZ
range_looprB   is_usedloopr   r   r    _iterate!  s    
z_SetPayload._iteratec          	   c   s   | j }| j}|tj}t|d}t|d}| j}|d}|d}t	
|| j}	|| ||V ||	}
||||
|}
||
|	 | |
}t|||j}|||| W dQ R X || ||	}
|
| _| |
V  dS )z
        Yield a random entry from the payload.  Caller must ensure the
        set isn't empty, otherwise the function won't end.
        r   r   Znext_entry_bodyZnext_entry_endN)rF   rG   r}   r   r~   r   r,   rN   rl   r   rj   rQ   rY   rp   rZ   rk   ro   r[   rU   r+   r)   cbranchrs   )rL   r   r   rv   zerorw   rN   rx   ry   rA   r\   rB   r   r   r   r    _next_entry5  s*    






z_SetPayload._next_entry)F)N)__name__
__module____qualname__rM   propertyrN   setterrO   rP   rQ   rR   rE   r   rU   r{   
contextlibcontextmanagerr   r   r   r   r   r    rD   a   s$   	

trD   c               @   sz  e Zd Zdd Zedd Zedd Zedd Zed	d
 Zedd Z	e	j
dd Z	dd Zdd ZdOddZdPddZdQddZdRddZdSddZdTddZdd  Zd!d" Zd#d$ Zd%d& Zd'd( Zd)d* Zd+d, Zd-d. Zd/d0 ZdUd2d3Zd4d5 Zd6d7 ZedVd9d:Z edWd;d<Z!ed=d> Z"ed?d@ Z#dAdB Z$dCdD Z%dEdF Z&dGdH Z'dXdIdJZ(dKdL Z)dMdN Z*d8S )YSetInstancec             C   s2   || _ || _|| _t||| _||||| _d S )N)rF   rG   rH   r$   
_entrysizemake_helper_set)rL   r   r   r   set_valr   r   r    rM   `  s
    zSetInstance.__init__c             C   s   | j jS )N)rH   rh   )rL   r   r   r    rh   g  s    zSetInstance.dtypec             C   s.   | j }| j}| j j|| j}t||| j|S )z/
        The _SetPayload for this set.
        )rF   rG   nrtmeminfo_datameminforD   rH   )rL   r   r   r   r   r   r    r   k  s    zSetInstance.payloadc             C   s
   | j  S )N)r   	_getvalue)rL   r   r   r    r1   w  s    zSetInstance.valuec             C   s   | j jS )N)r   r   )rL   r   r   r    r   {  s    zSetInstance.meminfoc             C   s   | j jS )N)r   parent)rL   r   r   r    r     s    zSetInstance.parentc             C   s   || j _d S )N)r   r   )rL   r1   r   r   r    r     s    c             C   s   | j jS )z<
        Return the number of elements in the size.
        )r   rO   )rL   r   r   r    get_size  s    zSetInstance.get_sizec             C   s    | j jr|rtjntj| j_d S )N)rH   Z	reflectedr   rt   ru   r   rR   )rL   valr   r   r    	set_dirty  s    zSetInstance.set_dirtyTc          	   C   s   | j }| j}|j}||_||_|j}	t|	jd}
||	|
 }	|_|j	t
|||dd ||j|
|_W d Q R X |r| |	 | d d S )Nr   T)likely)rF   rG   r)   rX   rO   r   r,   r-   ro   rW   r;   rP   upsizer   )rL   r   rB   re   r5   	do_resizer   r   old_hashrO   rw   r   r   r    
_add_entry  s    

zSetInstance._add_entryc          
   C   s   | j }| j}|j||dd\}}||}	||	 ||}
|
j}||
_||
_|j}t	
|jd}||| }|_|jt|||dd ||j||_W d Q R X |r| | | d W d Q R X d S )NT)rb   r   )r   )rF   rG   r{   not_rW   rU   r)   rX   rO   r   r,   r-   ro   r;   rP   r   r   )rL   r   re   r5   r   r   r   rg   r\   Z	not_foundrB   r   rO   rw   r   r   r    _add_key  s$    



zSetInstance._add_keyc             C   sV   t |jjt|_|j}t |jd}| j|| }|_|rH| | | 	d d S )Nr   T)
r   r,   r)   r-   r<   rO   rG   subdownsizer   )rL   r   rB   r   rO   rw   r   r   r    _remove_entry  s    
zSetInstance._remove_entryc       
   	   C   sN   | j }| j}|||\}}|| ||}	| ||	| W d Q R X |S )N)rF   rG   r{   rW   rU   r   )
rL   r   re   r5   r   r   r   rg   r\   rB   r   r   r    _remove_key  s    
zSetInstance._remove_keyc             C   s8   | j }| j}| j}t||| jj|}| |||| d S )N)rF   rG   r   r7   rH   rh   r   )rL   re   r   r   r   r   r5   r   r   r    ro     s
    zSetInstance.addc             C   s6   | j }| j}| j}| ||||}| |||| dS )z`A version of .add for use inside functions following Python calling
        convention.
        N)rF   rG   r   _pyapi_get_hash_valuer   )rL   pyapire   r   r   r   r   r5   r   r   r    	add_pyapi  s
    zSetInstance.add_pyapic          	      s    fdd}j jg}tj}|||}j ||||g\}	}
 j |	jdd$ j	 ||	  
|  W dQ R X |
S )z=Python API compatible version of `get_hash_value()`.
        c                st   j | |} j}tj|||dd}d|_t| }j 	|||\}t
|jj|}j || |S )Nz.set_hash_item)nameZinternal)	call_convZget_function_typemoduler   ZFunctionZget_unique_nameZlinkageZ	IRBuilderrl   Zdecode_argumentsr7   rH   rh   Zreturn_value)restyargtypesr2   modr4   Zinner_builderZ
inner_itemr5   )r   r   rL   r   r    emit_wrapper  s    z7SetInstance._pyapi_get_hash_value.<locals>.emit_wrapperF)r   N)rH   rh   r   r~   r   Zcall_functionrW   r   r6   Zraise_errorZretZget_null_object)rL   r   r   r   re   r   r   r   r4   ZstatusZretvalr   )r   r   rL   r    r     s    

z!SetInstance._pyapi_get_hash_valuec             C   s8   | j }| j}| j}t||| jj|}|||\}}|S )N)rF   rG   r   r7   rH   rh   r{   )rL   re   r   r   r   r5   rg   r\   r   r   r    contains  s    zSetInstance.containsc             C   s6   | j }| j}| j}t||| jj|}| |||}|S )N)rF   rG   r   r7   rH   rh   r   )rL   re   r   r   r   r5   rg   r   r   r    discard  s    zSetInstance.discardc          	   C   sd   | j }| j}|| jj}t||}| j}|  }|	|j
| | || W d Q R X ||S )N)rF   rG   r}   rH   rh   r   Zalloca_oncer   r   r[   rX   r   rZ   )rL   r   r   ZltyrX   r   rB   r   r   r    pop#  s    
zSetInstance.popc             C   s<   | j }| j}|tj}t|t}| | | 	d d S )NT)
rF   rG   r}   r   r~   r   r,   MINSIZE_replace_payloadr   )rL   r   r   rv   minsizer   r   r    clear1  s    
zSetInstance.clearc             C   s:  | j }| j}| j}|j}|j}t| ||| jd}|d||}|j|dd\}}	|@ |	|}
|j
||
dd |j|td W dQ R X W dQ R X |	 | |||}||}
|j
||
dd |j|td W dQ R X |j}| "}|j}|j||j|jdd W dQ R X W dQ R X W dQ R X |S )z,
        Return a copy of this set.
        Nz==T)r   F)zcannot copy set)r   )rF   rG   r   rO   rP   r-   rH   r9   if_else_copy_payloadrW   r   r   return_user_excMemoryErrorchoose_alloc_size_allocate_payloadr   rB   r   rX   r)   )rL   r   r   r   rO   rP   otherZno_deleted_entriesZif_no_deletedZ
if_deletedoknentriesother_payloadr   rB   r   r   r    copy:  s4    




&zSetInstance.copyc       
   
   C   s   | j }| j}| j}|j}| L}|j}||j|j\}}	||	| | j
||dd W dQ R X W dQ R X | |j dS )z9
        In-place intersection with *other* set.
        F)r   N)rF   rG   r   r   rB   r{   rX   r)   rW   r   r   r   rO   )
rL   r   r   r   r   r   r   rB   rg   _r   r   r    	intersecta  s    
$zSetInstance.intersectc          	   C   sX   | j }| j}| j}|j}| "}|j}| j||j|jdd W dQ R X | |j	 dS )z7
        In-place difference with *other* set.
        F)r   N)
rF   rG   r   r   rB   r   rX   r)   r   rO   )rL   r   r   r   r   r   r   rB   r   r   r    
differences  s    
 zSetInstance.differencec             C   s   | j }| j}|j}| }|jj}|jj}| j}|j||dd\}	}
||
}|	|	J\}}| | j
||dd W dQ R X | | |||| W dQ R X W dQ R X W dQ R X | | jj dS )zA
        In-place symmetric difference with *other* set.
        T)rb   F)r   N)rF   rG   r   r   rB   rX   r)   r{   rU   r   r   r   r   rO   )rL   r   r   r   r   r   rX   r5   r   rg   r\   rB   Z	if_commonZif_not_commonr   r   r    symmetric_difference  s    

.z SetInstance.symmetric_differenceFc             C   s   | j }| j}| j}|j}|r dnd}t|tj}||||j|j\}	}
|
 |	tj
| W d Q R X |	f | R}|j}||j|j\}}||| |	tj
| |  W d Q R X W d Q R X W d Q R X W d Q R X ||S )Nr?   z<=)rF   rG   r   r   rj   rt   r   r9   rO   r[   ru   r   rB   r{   rX   r)   rW   r   rC   rZ   )rL   r   strictr   r   r   r   Zcmp_opresZ
if_smaller	if_largerr   rB   rg   r   r   r   r    issubset  s&    
0zSetInstance.issubsetc          
      s   | j }| j | j}|j}t tj fdd}  d|j|j>\}}| ||| W d Q R X | ||| W d Q R X W d Q R X  	S )Nc          
      s^   |   L}|j}||j|j\}} |  tj |	  W d Q R X W d Q R X d S )N)
r   rB   r{   rX   r)   rW   r[   r   ru   rC   )ZsmallerZlargerr   rB   rg   r   )r   r   r   r    check  s    
z%SetInstance.isdisjoint.<locals>.check>)
rF   rG   r   r   rj   rt   r   r9   rO   rZ   )rL   r   r   r   r   r   r   	otherwiser   )r   r   r    
isdisjoint  s    	zSetInstance.isdisjointc             C   s   | j }| j}| j}|j}t|tj}||d|j|j\}}|f |	 R}	|	j
}
||
j|
j\}}||| |tj| |	  W d Q R X W d Q R X W d Q R X | |tj| W d Q R X W d Q R X ||S )Nz==)rF   rG   r   r   rj   rt   r   r9   rO   r   rB   r{   rX   r)   rW   r   r[   ru   rC   rZ   )rL   r   r   r   r   r   r   Zif_same_sizer   r   rB   rg   r   r   r   r    equals  s$    
&"zSetInstance.equalsNc       	      C   sf   | tj}|dkr"t|t}n$t|tr8t||}| |||}| |||d}|	|}||fS )z
        Allocate a SetInstance with its storage.
        Return a (ok, instance) tuple where *ok* is a LLVM boolean and
        *instance* is a SetInstance object (the object's contents are
        only valid when *ok* is true).
        N)
r}   r   r~   r   r,   r   
isinstanceintr   r   )	clsr   r   r   nitemsrv   r   rL   r   r   r   r    allocate_ex  s    

zSetInstance.allocate_exc          	   C   sH   |  ||||\}}|j||dd |j|td W dQ R X |S )z
        Allocate a SetInstance with its storage.  Same as allocate_ex(),
        but return an initialized *instance*.  If allocation failed,
        control is transferred to the caller using the target's current
        call convention.
        F)r   )zcannot allocate setN)r   rW   r   r   r   r   )r   r   r   r   r   r   rL   r   r   r    allocate  s
    
zSetInstance.allocatec             C   s<   | |||d}||j _|tj|j _|j|||j |S )z
        Allocate a new set instance pointing to an existing payload
        (a meminfo pointer).
        Note the parent field has to be filled by the caller.
        N)	r   r   get_constant_nullr   pyobjectr   r   Zincrefr1   )r   r   r   r   r   rL   r   r   r    from_meminfo  s
    zSetInstance.from_meminfoc          
   C   s   |j }t|d}t|t}|||}t||}|d}	|d}
||	 |	|	d |
|}|d||}|j|dd ||
 W dQ R X |||}||| ||	 W dQ R X ||
 |
|S )zT
        Choose a suitable number of entries for the given number of items.
        r   zcalcsize.bodyzcalcsize.endz>=F)r   N)r-   r   r,   r   shlr   rj   rl   rY   rp   rZ   r9   rW   r[   rs   )r   r   r   r   rv   rw   r   min_entriesZsize_prx   ry   r   Zis_large_enoughZ	next_sizer   r   r    r     s$    




zSetInstance.choose_alloc_sizec          
   C   s0  | j }| j}|j}t|d}t|d}| j}|||}||j|}	|	d||	}
|j
|
dd t||	}|d}|d}|| ||D ||}|||}||| |	d||}|||| W dQ R X || ||}tr||d	||	|| | ||d
 W dQ R X dS )zs
        When adding to the set, ensure it is properly sized for the given
        number of used entries.
        r      z>=F)r   zcalcsize.bodyzcalcsize.endNzKupsize to %zd items: current size = %zd, min entries = %zd, new size = %zd
zcannot grow set)rF   rG   r-   r   r,   r   r   ro   rN   r9   rW   r   rj   rl   rY   rp   rZ   r[   r   rs   DEBUG_ALLOCSprintf_resize)rL   r   r   r   rv   rw   twor   r   r   need_resize
new_size_prx   ry   new_sizeis_too_smallr   r   r    r   <  s6    





zSetInstance.upsizec             C   s  | j }| j}|j}t|d}t|d}t|t}| j}|||}	||	d|	||	|}	||	|}
|
|j|}||	d|
||	d||}|j|dd t||}|d}|d	}|| ||` ||}|||}|	d
|	|}|| || W dQ R X ||| || W dQ R X || ||}trr||d|||	| | ||d W dQ R X dS )zw
        When removing from the set, ensure it is properly sized for the given
        number of used entries.
        r   r   z>=z<=r?   F)r   zcalcsize.bodyzcalcsize.endr   NzMdownsize to %zd items: current size = %zd, min entries = %zd, new size = %zd
zcannot shrink set)rF   rG   r-   r   r,   r   r   r   r/   r9   ro   rN   rk   rW   r   rj   rl   rY   rp   rZ   rq   r[   rs   r   r   r   )rL   r   r   r   rv   rw   r   r   r   r   Zmax_sizer   r   r   rx   ry   r   r   r   r   r    r   j  sF    





zSetInstance.downsizec       
   	   C   s   | j }| j}|}| j|dd}|j||dd |j|t|f W dQ R X | j}|	 "}|j
}	| j||	j|	jdd W dQ R X | |j dS )zw
        Resize the payload to the given number of entries.

        CAUTION: *nentries* must be a power of 2!
        T)reallocF)r   N)r   )rF   rG   r   rW   r   r   r   r   r   r   rB   r   rX   r)   _free_payloadr   )
rL   r   r   errmsgr   r   Zold_payloadr   r   rB   r   r   r    r     s    

zSetInstance._resizec          	   C   s\   | j }| j}| | jj | j|dd}|j||dd |j	|t
d W dQ R X dS )z
        Replace the payload with a new empty payload with the given number
        of entries.

        CAUTION: *nentries* must be a power of 2!
        T)r   F)r   )zcannot reallocate setN)rF   rG   r   r   r   r   rW   r   r   r   r   )rL   r   r   r   r   r   r   r    r     s    
zSetInstance._replace_payloadc             C   s  | j }| j}t|tj}|tj}t	|d}t	|d}|
t| j}	||	}
| j}|
|8 }
t||t	||t	||
\}}|j|dd |tj| W dQ R X |j||dd |r| jj}|jj|||d}t||}n|jj||d}t||}|jt||dd\}}| |tj| W dQ R X |z |sr|| j_|tj| j_| j}t||j |d ||_!||_"||_#|$||}||_%t&r|'|d	||j | W dQ R X W dQ R X W dQ R X ||S )
z
        Allocate and initialize payload for the given number of entries.
        If *realloc* is True, the existing meminfo is reused.

        CAUTION: *nentries* must be a power of 2!
        r   r   F)r   NT)r      z.allocated %zd bytes for set at %p: mask = %zd
)(rF   rG   r   rj   rt   r}   r   r~   r   r,   r   r   rH   r#   r   Zmuladd_with_overflowrW   r[   ru   rZ   r   r   r   Zmeminfo_varsize_allocis_nullmeminfo_new_varsizer   r   r   r   r   Zmemsetr   rO   rP   rQ   r   rN   r   r   )rL   r   r   r   r   r   rv   r   rw   r   payload_size
entry_size	allocsizeZovfr   r   alloc_okif_errorif_okr   Znew_maskr   r   r    r     sV    


*zSetInstance._allocate_payloadc             C   s   | j j| j| j| dS )z9
        Free an allocated old payload at *ptr*.
        N)rF   r   Zmeminfo_varsize_freerG   r   )rL   r   r   r   r    r     s    zSetInstance._free_payloadc             C   s  | j }| j}t|tj}|tj}t	|d}t	|d}|
t| j}||}	| j}
|	|
8 }	|j}|||}|t	||	|t	||
|}|j||dd |jj||d}t||}|jt||dd\}}| |tj| W dQ R X |` || j_| j}|j|_|j|_||_||_t ||j!|j!||
 t"rj|#|d||j$| W dQ R X W dQ R X W dQ R X ||S )	z7
        Raw-copy the given payload into self.
        r   r   T)r   )r   FNz.allocated %zd bytes for set at %p: mask = %zd
)%rF   rG   r   rj   rt   r}   r   r~   r   r,   r   r   rH   r#   r   rN   ro   rr   rW   rZ   r   r   r   r   r[   ru   r   r   r   rO   rP   rQ   Z
raw_memcpyrE   r   r   r   )rL   Zsrc_payloadr   r   r   rv   r   rw   r   r   r   rN   r   r   r   r   r   r   r   r   r   r    r     sJ    

*zSetInstance._copy_payload)T)T)T)T)T)T)F)N)N)F)+r   r   r   rM   r   rh   r   r1   r   r   r   r   r   r   r   r   r   ro   r   r   r   r   r   r   r   r   r   r   r   r   r   classmethodr   r   r   r   r   r   r   r   r   r   r   r   r   r   r    r   ^  sP   





'			'
.<
?r   c               @   sZ   e Zd Zdd Zedd Zedd Zedd Zed	d
 Z	e	j
dd
 Z	dd ZdS )SetIterInstancec             C   sL   || _ || _|| _||||| _| j j|| j}t||| jj	|| _
d S )N)rF   rG   rH   r   _iterr   r   r   rD   	containerrI   )rL   r   r   	iter_typeZiter_valr   r   r   r    rM   Q  s    zSetIterInstance.__init__c             C   sJ   t |||j|}| |||d }|tjd}t|||j_|j	|j_	|S )Nr   )
r   r   get_constantr   r~   r   rj   r   rA   r   )r   r   r   r   r   Zset_instrL   rA   r   r   r    from_setY  s    
zSetIterInstance.from_setc             C   s
   | j  S )N)r   r   )rL   r   r   r    r1   b  s    zSetIterInstance.valuec             C   s   | j jS )N)r   r   )rL   r   r   r    r   f  s    zSetIterInstance.meminfoc             C   s   | j | jjS )N)rG   rZ   r   rA   )rL   r   r   r    rA   j  s    zSetIterInstance.indexc             C   s   | j || jj d S )N)rG   r[   r   rA   )rL   r1   r   r   r    rA   n  s    c          	   C   sr   | j }| j}t|jd}|  |j|d:}|j}|  |	|j
 | j|j || _ |  W d Q R X d S )Nr   )r|   )rA   rI   r   r,   r-   Zset_exhaustedr   rB   Z	set_validZyield_rX   rG   ro   rC   )rL   resultrA   r   rw   r   rB   r   r   r    iternextr  s    zSetIterInstance.iternextN)r   r   r   rM   r   r   r   r1   r   rA   r   r   r   r   r   r    r   O  s   	r   c          	   C   s   t |}t| |||}t||}t||}| tj|}t	||(}	|
t||d|	j}
||
 W dQ R X t| |||jS )zD
    Build a set of the given type, containing the given items.
    r   N)lenr   r   r   Z
pack_arrayrj   r   r   r~   rm   rZ   rS   rA   ro   r   r1   )r   r   r   itemsr   instZarrayZ	array_ptrcountr   re   r   r   r    	build_set  s    r   c             C   s$   |j }t| ||}t| |||jS )N)return_typer   r   r   r1   )r   r   r3   argsr   r   r   r   r    set_empty_constructor  s    r   c       
   	   C   sh   |j }|j\}|\}t| |||}t| |||}t| |||}	||	j W d Q R X t| |||jS )N)	r   r   r   r   r   r   ro   r1   r   )
r   r   r3   r   r   
items_typer   nr   r   r   r   r    set_constructor  s    r  c             C   s    t | ||jd |d }| S )Nr   )r   r   r   )r   r   r3   r   r   r   r   r    set_len  s    r  c             C   s&   t | ||jd |d }||d S )Nr   r   )r   r   r   )r   r   r3   r   r   r   r   r    in_set  s    r  Zgetiterc             C   s(   t | ||j|d }t| ||j|jS )Nr   )r   r   r   r   r1   )r   r   r3   r   r   r   r   r    getiter_set  s    r  r   c             C   s&   t | ||jd |d }|| d S )Nr   )r   r   r   )r   r   r3   r   r   r   r   r   r    iternext_listiter  s    r  zset.addc             C   s2   t | ||jd |d }|d }|| |  S )Nr   r   )r   r   ro   get_dummy_value)r   r   r3   r   r   re   r   r   r    set_add  s    
r  zset.discardc             C   s2   t | ||jd |d }|d }|| |  S )Nr   r   )r   r   r   r  )r   r   r3   r   r   re   r   r   r    set_discard  s    
r  zset.popc          	   C   sZ   t | ||jd |d }|jj}|jt||dd | j|t	d W d Q R X |
 S )Nr   F)r   )zset.pop(): empty set)r   r   r   rO   rW   r   r   r   r   KeyErrorr   )r   r   r3   r   r   rO   r   r   r    set_pop  s    
r
  z
set.removec          	   C   sb   t | ||jd |d }|d }||}|j||dd | j|td W d Q R X |  S )Nr   r   F)r   )zset.remove(): key not in set)	r   r   r   rW   r   r   r   r	  r  )r   r   r3   r   r   re   rg   r   r   r    
set_remove  s    

r  z	set.clearc             C   s(   t | ||jd |d }|  |  S )Nr   )r   r   r   r  )r   r   r3   r   r   r   r   r    	set_clear  s    r  zset.copyc             C   s2   t | ||jd |d }| }t| ||j|jS )Nr   )r   r   r   r   r   r1   )r   r   r3   r   r   r   r   r   r    set_copy  s    r  zset.difference_updatec             C   sB   t | ||jd |d }t | ||jd |d }|| |  S )Nr   r   )r   r   r   r  )r   r   r3   r   r   r   r   r   r    set_difference_update  s    
r  zset.intersection_updatec             C   sB   t | ||jd |d }t | ||jd |d }|| |  S )Nr   r   )r   r   r   r  )r   r   r3   r   r   r   r   r   r    set_intersection_update
  s    
r  zset.symmetric_difference_updatec             C   sB   t | ||jd |d }t | ||jd |d }|| |  S )Nr   r   )r   r   r   r  )r   r   r3   r   r   r   r   r   r    set_symmetric_difference_update  s    
r  z
set.updatec       
   	   C   s   t | ||jd |d }|jd }|d }t| |||}|d k	rZ||jj|}|| t| |||}	||	j W d Q R X |d k	r|	|jj | 
 S )Nr   r   )r   r   r   ro   r   rO   r   r   r1   r   r  )
r   r   r3   r   r   r   r   r   r   r   r   r   r    
set_update  s    

r  c             C   s:   |j |jd kst|| ||| t| ||jd |d S )Nr   )r   r   AssertionErrorr   )r   r   r3   r   op_implr   r   r    set_inplace8  s    r  zset.differencec             C   s   dd }|  ||||S )Nc             S   s   |   }|| |S )N)r   difference_update)absr   r   r    difference_implD  s    
z'set_difference.<locals>.difference_impl)compile_internal)r   r   r3   r   r  r   r   r    set_differenceA  s    r  zset.intersectionc             C   s   dd }|  ||||S )Nc             S   s@   t | t |k r&|  }|| |S | }||  |S d S )N)r   r   intersection_update)r  r  r  r   r   r    intersection_implN  s    

z+set_intersection.<locals>.intersection_impl)r  )r   r   r3   r   r  r   r   r    set_intersectionK  s    
r  zset.symmetric_differencec             C   s   dd }|  ||||S )Nc             S   s@   t | t |kr&|  }|| |S | }||  |S d S )N)r   r   symmetric_difference_update)r  r  r  r   r   r    symmetric_difference_impl]  s    

z;set_symmetric_difference.<locals>.symmetric_difference_impl)r  )r   r   r3   r   r   r   r   r    set_symmetric_differenceZ  s    
r!  z	set.unionc             C   s   dd }|  ||||S )Nc             S   s@   t | t |kr&|  }|| |S | }||  |S d S )N)r   r   update)r  r  r  r   r   r    
union_implm  s    

zset_union.<locals>.union_impl)r  )r   r   r3   r   r#  r   r   r    	set_unionj  s    
r$  zset.isdisjointc             C   s:   t | ||jd |d }t | ||jd |d }||S )Nr   r   )r   r   r   )r   r   r3   r   r   r   r   r   r    set_isdisjoint|  s    r%  zset.issubsetc             C   s:   t | ||jd |d }t | ||jd |d }||S )Nr   r   )r   r   r   )r   r   r3   r   r   r   r   r   r    set_issubset  s    r&  zset.issupersetc             C   s   dd }|  ||||S )Nc             S   s
   | | S )N)r   )r  r  r   r   r    superset_impl  s    z%set_issuperset.<locals>.superset_impl)r  )r   r   r3   r   r'  r   r   r    set_issuperset  s    r(  c             C   s:   t | ||jd |d }t | ||jd |d }||S )Nr   r   )r   r   r   )r   r   r3   r   r   r   r   r   r    r%    s    c             C   s   dd }|  ||||S )Nc             S   s
   | |k S )Nr   )r  r  r   r   r    ne_impl  s    zset_ne.<locals>.ne_impl)r  )r   r   r3   r   r)  r   r   r    set_ne  s    r*  c             C   s>   t | ||jd |d }t | ||jd |d }|j|ddS )Nr   r   T)r   )r   r   r   )r   r   r3   r   r   r   r   r   r    set_lt  s    r+  c             C   s   dd }|  ||||S )Nc             S   s   || k S )Nr   )r  r  r   r   r    gt_impl  s    zset_gt.<locals>.gt_impl)r  )r   r   r3   r   r,  r   r   r    set_gt  s    r-  c             C   s^   t | ||jd |d }t | ||jd |d }||jtj}||jtj}|d||S )Nr   r   z==)r   r   Zptrtointr   r   rv   Zicmp_signed)r   r   r3   r   r  r  ZmaZmbr   r   r    set_is  s
    r.  c             C   s   |j |j kst|S )N)rh   r  )r   r   ZfromtyZtotyr   r   r   r    
set_to_set  s    r/  )e__doc__Z
__future__r   r   r   collectionsr   Zmathri   Zllvmliter   Znumbar   r   r   Znumba.targets.imputilsr	   r
   r   r   r   r   r   r   Znumba.utilsr    r   r   r!   r$   r8   r<   r.   r   rn   r   r7   r;   r>   r+   
namedtupler@   objectrD   r   r   r   setr   ZIterableTyper  r   Setr  r   ZAnyr  r  ZSetIterr  r  r  r
  r  r  r  r  r  r  r  iandiorisubixorZop_r  r  r   r  rk   r  xorr!  or_r$  r%  ler&  ger(  r]   ner*  ltr+  gtr-  is_r.  r/  r   r   r   r    <module>   s   (	 ~     v6

				