o
    ٰi*                     @  s  d Z ddlmZ ddlZddlZddlZddlmZmZm	Z	m
Z
mZmZ ddlmZmZ ddlmZ ejdkrVdd	lmZ dd
lmZmZmZmZ ddlmZ ddlmZ ndd	lmZ dd
lmZmZmZmZ ddlmZ ddlmZ ddgZe
dZe
dZ e
dZ!e
dZ"e# Z$d)ddZ%edG d d dej&ee Z'G d!d" d"ee  ZG d#d$ d$ee! ZG d%d& d&ee e!f Zed'G d(d dej&ee e!f Z(dS )*zContainer classes.    )annotationsN)AnyCallableSupportsIndexTypeVarcastoverload   )_ffi_apicore)register_object)   	   	ItemsView)IterableIteratorMappingSequenceKeysView
ValuesViewArrayMapTKV	_DefaultTobjr   elem_getterCallable[[Any, int], T]lengthintidxSupportsIndex | slicereturnT | list[T]c           	   
     s   t |tr||\}}} fddt|||D S zt|}W n ty9 } ztdt|j |d}~ww || k sC||krMt	d| d| |dk rU||7 } |S )a  Implement a pythonic __getitem__ helper.

    Parameters
    ----------
    obj
        The original object

    elem_getter
        A simple function that takes index and return a single element.

    length
        The size of the array

    idx
        The argument passed to getitem

    Returns
    -------
    result
        The element for integer indices or a :class:`list` for slices.

    c                   s   g | ]} |qS  r(   ).0ir    r   r(   E/home/ubuntu/.local/lib/python3.10/site-packages/tvm_ffi/container.py
<listcomp>q   s    z"getitem_helper.<locals>.<listcomp>z(indices must be integers or slices, not NzIndex out of range. size: z, got index r   )

isinstancesliceindicesrangeoperatorindex	TypeErrortype__name__
IndexError)	r   r    r"   r$   startstopstepr3   excr(   r+   r,   getitem_helperS   s   

r<   z	ffi.Arrayc                   @  s   e Zd ZdZd*ddZed+ddZed,ddZd-ddZd.ddZd/ddZd0ddZ	d1dd Z
d2d!d"Zd3d%d&Zd3d'd(Zd)S )4r   a<  Array container that represents a sequence of values in the FFI.

    :py:func:`tvm_ffi.convert` will map python list/tuple to this class.

    Parameters
    ----------
    input_list
        The list of values to be stored in the array.

    Examples
    --------
    .. code-block:: python

        import tvm_ffi

        a = tvm_ffi.Array([1, 2, 3])
        assert tuple(a) == (1, 2, 3)

    Notes
    -----
    For structural equality and hashing, use ``structural_equal`` and ``structural_hash`` APIs.

    See Also
    --------
    :py:func:`tvm_ffi.convert`

    
input_listIterable[T]r&   Nonec                 C  s   | j tjg|R   dS )z*Construct an Array from a Python sequence.N)__init_handle_by_constructor__r
   r   )selfr=   r(   r(   r,   __init__   s   zArray.__init__r$   r   r   c                C     d S Nr(   rA   r$   r(   r(   r,   __getitem__      zArray.__getitem__r/   list[T]c                C  rC   rD   r(   rE   r(   r(   r,   rF      rG   r%   r'   c                C  s   t | }t| tj||}|S )z)Return one element or a list for a slice.)lenr<   r
   ArrayGetItem)rA   r$   r"   resultr(   r(   r,   rF      s   r#   c                 C  
   t | S )z+Return the number of elements in the array.)r
   	ArraySizerA   r(   r(   r,   __len__      
zArray.__len__Iterator[T]c                 c  s&    t | }t|D ]}| | V  q	dS )z'Iterate over the elements in the array.N)rI   r1   )rA   r"   r*   r(   r(   r,   __iter__   s
   zArray.__iter__strc                 C  s6   |   dkrt| jd S dddd | D  d S )z,Return a string representation of the array.r   (chandle=None)[, c                 S  s   g | ]}|  qS r(   __repr__)r)   xr(   r(   r,   r-      s    z"Array.__repr__.<locals>.<listcomp>])__chandle__r5   r6   joinrN   r(   r(   r,   rX      s   zArray.__repr__valueobjectboolc                 C  s   t | |S )z$Check if the array contains a value.)r
   ArrayContains)rA   r]   r(   r(   r,   __contains__      zArray.__contains__c                 C     t | dkS )z&Return True if the array is non-empty.r   rI   rN   r(   r(   r,   __bool__   rb   zArray.__bool__otherArray[T]c                 C  s   t | t| |S zConcatenate two arrays.r5   	itertoolschainrA   rf   r(   r(   r,   __add__      zArray.__add__c                 C  s   t | t|| S rh   ri   rl   r(   r(   r,   __radd__   rn   zArray.__radd__N)r=   r>   r&   r?   )r$   r   r&   r   )r$   r/   r&   rH   )r$   r%   r&   r'   r&   r#   )r&   rQ   r&   rS   )r]   r^   r&   r_   r&   r_   )rf   r>   r&   rg   )r6   
__module____qualname____doc__rB   r   rF   rO   rR   rX   ra   re   rm   ro   r(   r(   r(   r,   r      s    
!






c                   @  8   e Zd ZdZdddZdd	d
ZdddZdddZdS )r   z!Helper class to return keys view.backend_map	Map[K, V]r&   r?   c                 C  
   || _ d S rD   _backend_maprA   rw   r(   r(   r,   rB         
zKeysView.__init__r#   c                 C  
   t | jS rD   rI   r{   rN   r(   r(   r,   rO      r}   zKeysView.__len__Iterator[K]c                 c  L    t | j}t| j}t|D ]}tt|d}|V  |ds# d S qd S )Nr      )rI   r{   r
   MapForwardIterFunctorr1   r   r   )rA   sizefunctor_keyr(   r(   r,   rR         
zKeysView.__iter__kr^   r_   c                 C  s
   || j v S rD   rz   rA   r   r(   r(   r,   ra      r}   zKeysView.__contains__Nrw   rx   r&   r?   rp   r&   r   r   r^   r&   r_   r6   rs   rt   ru   rB   rO   rR   ra   r(   r(   r(   r,   r      s    


	r   c                   @  s.   e Zd ZdZdddZdd	d
ZdddZdS )r   z#Helper class to return values view.rw   rx   r&   r?   c                 C  ry   rD   rz   r|   r(   r(   r,   rB      r}   zValuesView.__init__r#   c                 C  r~   rD   r   rN   r(   r(   r,   rO      r}   zValuesView.__len__Iterator[V]c                 c  r   )Nr	   r   )rI   r{   r
   r   r1   r   r   )rA   r   r   r   r]   r(   r(   r,   rR      r   zValuesView.__iter__Nr   rp   )r&   r   )r6   rs   rt   ru   rB   rO   rR   r(   r(   r(   r,   r      s
    

r   c                   @  rv   )r   z"Helper class to return items view.rw   rx   r&   r?   c                 C  ry   rD   rz   r|   r(   r(   r,   rB      r}   zItemsView.__init__r#   c                 C  r~   rD   r   rN   r(   r(   r,   rO     r}   zItemsView.__len__Iterator[tuple[K, V]]c                 c  s^    t | j}t| j}t|D ]}tt|d}tt|d}||fV  |ds, d S qd S )Nr   r	   r   )rI   r{   r
   r   r1   r   r   r   )rA   r   r   r   r   r]   r(   r(   r,   rR     s   

zItemsView.__iter__itemr^   r_   c                 C  sD   t |trt|dkrdS |\}}| j|t}|tu rdS ||kS )Nr   F)r.   tuplerI   r{   getMISSING)rA   r   r   r]   actual_valuer(   r(   r,   ra     s   zItemsView.__contains__Nr   rp   )r&   r   )r   r^   r&   r_   r   r(   r(   r(   r,   r      s    



r   zffi.Mapc                   @  s   e Zd ZdZd/ddZd0ddZd1ddZd2ddZd3ddZd4ddZ	d5ddZ
d6ddZd7d d!Zed8d$d%Zed9d(d%Zd:d;d+d%Zd<d-d.Zd)S )=r   aE  Map container.

    :py:func:`tvm_ffi.convert` will map python dict to this class.

    Parameters
    ----------
    input_dict
        The dictionary of values to be stored in the map.

    Examples
    --------
    .. code-block:: python

        import tvm_ffi

        amap = tvm_ffi.Map({"a": 1, "b": 2})
        assert len(amap) == 2
        assert amap["a"] == 1
        assert amap["b"] == 2

    Notes
    -----
    For structural equality and hashing, use ``structural_equal`` and ``structural_hash`` APIs.

    See Also
    --------
    :py:func:`tvm_ffi.convert`

    
input_dictMapping[K, V]r&   r?   c                 C  sB   g }|  D ]\}}|| || q| jtjg|R   dS )z&Construct a Map from a Python mapping.N)itemsappendr@   r
   r   )rA   r   list_kvsr   vr(   r(   r,   rB   @  s
   
zMap.__init__r   r   r   c                 C  s   t tt| |S )z/Return the value for key `k` or raise KeyError.)r   r   r
   
MapGetItemr   r(   r(   r,   rF   H  s   zMap.__getitem__r^   r_   c                 C  s   t | |dkS )z(Return True if the map contains key `k`.r   )r
   MapCountr   r(   r(   r,   ra   L  s   zMap.__contains__KeysView[K]c                 C     t | S )z(Return a dynamic view of the map's keys.r   rN   r(   r(   r,   keysP     zMap.keysValuesView[V]c                 C  r   )z*Return a dynamic view of the map's values.r   rN   r(   r(   r,   valuesT  r   z
Map.valuesItemsView[K, V]c                 C  r   )zGet the items from the map.r   rN   r(   r(   r,   r   X  r   z	Map.itemsr#   c                 C  rL   )z&Return the number of items in the map.)r
   MapSizerN   r(   r(   r,   rO   \  rP   zMap.__len__c                 C  rc   )z$Return True if the map is non-empty.r   rd   rN   r(   r(   r,   re   `  rb   zMap.__bool__r   c                 C  s   t |  S )zIterate over the map's keys.)iterr   rN   r(   r(   r,   rR   d  rb   zMap.__iter__r   V | Nonec                 C  rC   rD   r(   )rA   r   r(   r(   r,   r   h  rG   zMap.getdefaultV | _DefaultTc                 C  rC   rD   r(   )rA   r   r   r(   r(   r,   r   k  rG   NV | _DefaultT | Nonec                 C  s   t | |}t|r|S |S )zGet an element with a default value.

        Parameters
        ----------
        key
            The attribute key.

        default
            The default object.

        Returns
        -------
        value
            The result value.

        )r
   MapGetItemOrMissingr   same_as)rA   r   r   retr(   r(   r,   r   n  s   
rS   c                 C  s:   |   dkrt| jd S dddd |  D  d S )z*Return a string representation of the map.r   rT   {rV   c                 S  s&   g | ]\}}|   d |   qS )z: rW   )r)   r   r   r(   r(   r,   r-     s   & z Map.__repr__.<locals>.<listcomp>})r[   r5   r6   r\   r   rN   r(   r(   r,   rX     s    zMap.__repr__)r   r   r&   r?   )r   r   r&   r   r   )r&   r   )r&   r   )r&   r   rp   rr   r   )r   r   r&   r   )r   r   r   r   r&   r   rD   )r   r   r   r   r&   r   rq   )r6   rs   rt   ru   rB   rF   ra   r   r   r   rO   re   rR   r   r   rX   r(   r(   r(   r,   r     s"    
#







)
r   r   r    r!   r"   r#   r$   r%   r&   r'   ))ru   
__future__r   rj   r2   systypingr   r   r   r   r   r    r
   r   registryr   version_infocollections.abcr   ItemsViewBaser   r   r   r   r   KeysViewBaser   ValuesViewBase__all__r   r   r   r   MapGetMissingObjectr   r<   Objectr   r   r(   r(   r(   r,   <module>   s>    	

,T"