B
      ›\`  ã               @   sê   d Z ddlZddlm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 dd	„ Zd
d„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zeee ej¡ƒdd„ ƒZeejdƒdd„ ƒZeejdƒdd„ ƒZeejdƒdd „ ƒZdS )!z2
Implement slices and various slice computations.
é    N)Úir)Úzip_longest)ÚcgutilsÚtypesÚtypingé   )Úlower_builtinÚlower_getattrÚiternext_implÚimpl_ret_borrowedÚimpl_ret_new_refÚimpl_ret_untrackedc             C   s2   |   d|t |jd¡¡}|  ||¡}|  |||¡S )z^
    Fix negative index by adding *size* to it.  Positive
    indices are left untouched.
    ú<r   )Úicmp_signedr   ÚConstantÚtypeÚaddÚselect)ÚbuilderÚidxÚsizeZis_negativeZwrapped_index© r   ú4lib/python3.7/site-packages/numba/targets/slicing.pyÚ	fix_index   s    r   c       	   
      s¶   t  ˆjd¡‰t  ˆjd¡}‡ ‡‡‡fdd„}ˆ  t ˆ ˆj¡¡j\}}| |dˆˆƒ |dˆˆƒ W dQ R X |. |}ˆ  ˆ|¡}|d||ƒ |d||ƒ W dQ R X W dQ R X dS )zˆ
    Fix *slice* start and stop to be valid (inclusive and exclusive, resp)
    indexing bounds for a sequence of the given *size*.
    r   éÿÿÿÿc          	      sŽ   t ˆ| ƒ}tˆ |ˆƒ}tˆ| |ƒ ˆ  d|ˆ¡}ˆ j|dd tˆ| |ƒ W d Q R X ˆ  d|ˆ¡}ˆ j|dd tˆ| |ƒ W d Q R X d S )Nr   F)Zlikelyz>=)Úgetattrr   Úsetattrr   Zif_then)Z
bound_nameZ
lower_replZ
upper_replZboundZ	underflowZoverflow)r   r   ÚsliceÚzeror   r   Ú	fix_bound#   s    
zfix_slice.<locals>.fix_boundÚstartÚstopN)r   r   r   Zif_elser   Ú
is_neg_intÚstepr   )	r   r   r   Z	minus_oner   Zif_neg_stepZif_pos_stepÚlowerÚupperr   )r   r   r   r   r   Ú	fix_slice   s    r&   c          	   C   s°   |j }|j}|j}t |jd¡}t |jd¡}t | |¡}|  ||¡}|  ||¡}	|  	||¡}
|  
||
|	¡}|  	||  ||¡¡}|  
||  d||¡|  d||¡¡}|  
|||¡S )a   
    Given a slice, compute the number of indices it spans, i.e. the
    number of iterations that for_range_slice() will execute.

    Pseudo-code:
        assert step != 0
        if step > 0:
            if stop <= start:
                return 0
            else:
                return (stop - start - 1) // step + 1
        else:
            if stop >= start:
                return 0
            else:
                return (stop - start + 1) // step + 1

    (see PySlice_GetIndicesEx() in CPython)
    r   r   z>=z<=)r    r!   r#   r   r   r   r   r"   Úsubr   r   Zsdivr   )r   Úslicestructr    r!   r#   Úoner   Úis_step_negativeZdeltaZpos_dividendZneg_dividendZdividendZnominal_lengthZis_zero_lengthr   r   r   Úget_slice_length>   s    r+   c       	      C   sd   |j }|j}| d¡}| d¡}|  d|j|¡}|  ||  ||¡|¡}|  ||  ||¡|¡}||fS )z?
    Return the [lower, upper) indexing bounds of a slice.
    r   r   r   )r    r!   r   r   r#   r   r   )	r   r(   r    r!   r   r)   r*   r$   r%   r   r   r   Úget_slice_boundsj   s    

r,   c             C   s   |   |j|¡S )z4
    Fix the given stride for the slice's step.
    )Úmulr#   )r   r   Zstrider   r   r   Ú
fix_stride|   s    r.   c             C   s    |j rt | ||jtdf¡ dS )zP
    Guard against *slicestruct* having a zero step (and raise ValueError).
    zslice step cannot be zeroN)Úhas_stepr   Z
guard_nullr#   Ú
ValueError)Úcontextr   Útypr(   r   r   r   Úguard_invalid_slice‚   s    r3   c             C   s&   d| j d > d }d||| d dfS )z©
    Get the default values for a slice's members:
    (start for positive step, start for negative step,
     stop for positive step, stop for negative step, step)
    r   r   )Zaddress_size)r1   Zmaxintr   r   r   Úget_defaults‹   s    r4   c                s  ‡ fdd„t ˆ ƒD ƒ\}}}}}d gd ‰x<tt|j|ƒƒD ](\}	\}
}|
tjkr\d ˆ|	< q<|ˆ|	< q<W ‡fdd„}|d|ƒ}| d|ˆ  tjd¡¡}| 	|||¡}| 	|||¡}|d	|ƒ}|d|ƒ}|j
}
ˆ  ||j
¡}||_||_||_| ¡ }tˆ ||j
|ƒS )
Nc                s   g | ]}ˆ   tj|¡‘qS r   )Úget_constantr   Úintp)Ú.0Úx)r1   r   r   ú
<listcomp>›   s    z*slice_constructor_impl.<locals>.<listcomp>é   c                s   ˆ |  }|d kr|S |S d S )Nr   )ÚiÚdefaultÚval)Ú
slice_argsr   r   Úget_arg_value¦   s    z-slice_constructor_impl.<locals>.get_arg_valueé   r   r   r   )r4   Ú	enumerateÚzipÚargsr   Znoner   r5   r6   r   Zreturn_typeÚmake_helperr    r!   r#   Z	_getvaluer   )r1   r   ZsigrC   Zdefault_start_posZdefault_start_negZdefault_stop_posZdefault_stop_negZdefault_stepr;   Ztyr=   r?   r#   r*   Zdefault_stopZdefault_startr!   r    ÚsliZresr   )r1   r>   r   Úslice_constructor_impl˜   s.     





rF   r    c             C   s   |   |||¡}|jS )N)rD   r    )r1   r   r2   ÚvaluerE   r   r   r   Úslice_start_implÁ   s    rH   r!   c             C   s   |   |||¡}|jS )N)rD   r!   )r1   r   r2   rG   rE   r   r   r   Úslice_stop_implÆ   s    rI   r#   c             C   s,   |j r|  |||¡}|jS |  tjd¡S d S )Nr   )r/   rD   r#   r5   r   r6   )r1   r   r2   rG   rE   r   r   r   Úslice_step_implË   s    rJ   ) Ú__doc__Ú	itertoolsZllvmliter   Znumba.six.movesr   Znumbar   r   r   Zimputilsr   r	   r
   r   r   r   r   r&   r+   r,   r.   r3   r4   r   ZVarArgZAnyrF   Z	SliceTyperH   rI   rJ   r   r   r   r   Ú<module>   s     
$,	)