
    xKg,                         d Z ddlmZ ddlmZmZmZ ddl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  G d d      Zd	 Zd
 Zd Zd Zd Zed        Z G d d      Zy)zUtilities for defining a mutable struct.

A mutable struct is passed by reference;
hence, structref (a reference to a struct).

    )njit)typesimputilscgutils)default_managermodels)infer_getattrlower_getattr_genericlower_setattr_genericboxunboxNativeValue	intrinsicoverload)AttributeTemplatec                   .    e Zd ZdZd Zd Zd Zd Zd Zy)_Utilsz;Internal builder-code utils for structref definitions.
    c                 .    || _         || _        || _        y)z
        Parameters
        ----------
        context :
            a numba target context
        builder :
            a llvmlite IRBuilder
        struct_type : numba.core.types.StructRef
        N)contextbuilderstruct_type)selfr   r   r   s       `/home/alanp/www/video.onchill/myenv/lib/python3.12/site-packages/numba/experimental/structref.py__init__z_Utils.__init__   s     &    c                     | j                   }| j                  }| j                  } t        j                  |      ||      }||_        |S )zKEncapsulate the MemInfo from a `StructRefPayload` in a `StructRef`
        )r   r   r   r   create_struct_proxymeminfo)r   mir   r   r   sts         r   new_struct_refz_Utils.new_struct_ref(   sF     ,,,,&&5W((5gwG
	r   c                     | j                   }| j                  }| j                  } t        j                  |      |||      S )z6Return a helper for accessing a StructRefType
        )value)r   r   r   r   r   )r   valr   r   r   s        r   get_struct_refz_Utils.get_struct_ref3   sB     ,,,,&&7w**;7WC
 	
r   c                 ^   | j                   }| j                  }| j                  }| j                  |      }|j                  }|j
                  j                  ||      }|j                         }|j                  |   }	|	j                         }
|j                  ||
j                               }|S )zDGet the data pointer to the payload from a `StructRefType`.
        )r   r   r   r%   r   nrtmeminfo_dataget_data_typedata_model_managerget_value_typebitcast
as_pointer)r   r$   r   r   r   	structvalr   data_ptrvaltypemodel
alloc_types              r   get_data_pointerz_Utils.get_data_pointer>   s     ,,,,&&'',	##;;++GW=++-**73))+
??8Z-B-B-DEr   c                     | j                   }| j                  }| j                  }| j                  |      }|j	                         } t        j                  |      |||      }|S )zFGet a getter/setter helper for accessing a `StructRefPayload`
        )ref)r   r   r   r3   r)   r   r   )r   r$   r   r   r   r/   r0   datavals           r   get_data_structz_Utils.get_data_structO   sd     ,,,,&&((-++-6'--g6W(
 r   N)	__name__
__module____qualname____doc__r   r!   r%   r3   r7    r   r   r   r      s     '		
"r   r   c                 ~     t          G  fddt                     }t               d        }t               d        }y)zDefine attributes on `struct_typeclass`.

    Defines both setters and getters in jit-code.

    This is called directly in `register()`.
    c                       e Zd ZW  Zd Zy)*define_attributes.<locals>.StructAttributec                 B    ||j                   v r|j                   |   }|S y N)
field_dict)r   typattrattrtys       r   generic_resolvez:define_attributes.<locals>.StructAttribute.generic_resolvei   s&    s~~%- &r   N)r8   r9   r:   keyrF   )struct_typeclasss   r   StructAttributer?   e   s    	r   rI   c                     t        | ||      }|j                  |      }t        ||      }|j                  |   }t	        j
                  | |||      S rA   )r   r7   getattrrB   r   impl_ret_borrowed)	r   r   rC   r$   rD   utilsr6   ret	fieldtypes	            r   struct_getattr_implz.define_attributes.<locals>.struct_getattr_impln   sQ    w-'',gt$NN4(	))'7IsKKr   c                 T   |j                   \  }}|\  }}t        | ||      }	|	j                  |      }
|j                  |   }| j	                  ||||      }t        |
|      }| j                  j                  |||       | j                  j                  |||       t        |
||       y rA   )
argsr   r7   rB   castrK   r'   increfdecrefsetattr)r   r   sigrR   rD   	inst_typeval_typeinstancer$   rM   r6   
field_typecasted	old_values                 r   struct_setattr_implz.define_attributes.<locals>.struct_setattr_implv   s     #H3w3''1))$/
gsHjAGT*	7Hf57Hi8v&r   N)r	   r   r
   r   )rH   rI   rP   r^   s   `   r   define_attributesr_   ^   sU     +   +,L -L +,' -'r   c                     | t         j                  u rt        dt         j                         |j                  t	        |       fd       }t        |       d        }y)a  Define the boxing & unboxing logic for `struct_type` to `obj_class`.

    Defines both boxing and unboxing.

    - boxing turns an instance of `struct_type` into a PyObject of `obj_class`
    - unboxing turns an instance of `obj_class` into an instance of
      `struct_type` in jit-code.


    Use this directly instead of `define_proxy()` when the user does not
    want any constructor to be defined.
    cannot register c                    t        |j                  |j                  |       }|j                  |      }|j                  }t        j                  t
        j                        }|j                  ||      }|j                  j                  |j                  j                              }|j                  j                  |j                  j                  |             }	|j                  j                  ||	|g      }
|j                  j                  |       |j                  j                  |	       |j                  j                  |       |
S )z8
        Convert a raw pointer to a Python int.
        )r   r   r   r%   r   r   MemInfoPointervoidptrr   pyapiunserializeserialize_objectcall_function_objargsrU   )rC   r$   crM   
struct_refr   mip_typeboxed_meminfoctor_pyfuncty_pyobjresobj_ctors              r   box_struct_refz%define_boxing.<locals>.box_struct_ref   s    
 qyy!))S1))#.
$$''6h0gg))!''*B*B8*LM77&&qww'?'?'DEgg++(M2
 	
{#	x 	}%
r   c                    |j                   j                  |d      }t        j                  t        j                        }|j                  ||      j                  }t        |j                  |j                  |       }|j                  |      }|j                         }|j                   j                  |       t        |      S )N_meminfo)re   object_getattr_stringr   rc   rd   r   r#   r   r   r   r!   	_getvaluerU   r   )	rC   objri   mi_objrk   r   rM   rj   outs	            r   unbox_struct_refz'define_boxing.<locals>.unbox_struct_ref   s    ..sJ?''6WWXv&,,qyy!))S1))"-
""$	v3r   N)r   	StructRef
ValueError_numba_box_r   r   )r   	obj_classrq   ry   rp   s       @r   define_boxingr~      sd     eoo%+EOO+<=>>$$H , ;   r   c                 .   dj                  |      }d}g }|D ]  }|j                  d| d|         d| j                  |      }d| dt        |       d| d	| d
| d}t        |t              }	t        ||	       |	d   }
 t        |       |
       y)zDefine the jit-code constructor for `struct_typeclass` using the
    Python type `py_class` and the required `fields`.

    Use this instead of `define_proxy()` if the user does not want boxing
    logic defined.
    z, z        zst.z = 
z

def ctor(z/):
    struct_type = struct_typeclass(list(zip(z, [z])))
    def impl(z)):
        st = new(struct_type)
        z#
        return st
    return impl
)rH   newctorN)joinappendlistdictr   execr   )py_classrH   fieldsparamsindentinit_fields_bufkinit_fieldssourceglbsr   s              r   define_constructorr      s     YYvFFOQCs1#/ vh-$$_5K

 --1&\N#fX FX 		 F !1s;D<DHXtr   c                 6    t        | ||       t        ||        y)a  Defines a PyObject proxy for a structref.

    This makes `py_class` a valid constructor for creating a instance of
    `struct_typeclass` that contains the members as defined by `fields`.

    Parameters
    ----------
    py_class : type
        The Python class for constructing an instance of `struct_typeclass`.
    struct_typeclass : numba.core.types.Type
        The structref type class to bind to.
    fields : Sequence[str]
        A sequence of field names.

    Returns
    -------
    None
    N)r   r~   )r   rH   r   s      r   define_proxyr      s    & x!16:"H-r   c                     | t         j                  u rt        dt         j                         t        j                  | t
        j                         t        |        | S )a  Register a `numba.core.types.StructRef` for use in jit-code.

    This defines the data-model for lowering an instance of `struct_type`.
    This defines attributes accessor and mutator for an instance of
    `struct_type`.

    Parameters
    ----------
    struct_type : type
        A subclass of `numba.core.types.StructRef`.

    Returns
    -------
    struct_type : type
        Returns the input argument so this can act like a decorator.

    Examples
    --------

    .. code-block::

        class MyStruct(numba.core.types.StructRef):
            ...  # the simplest subclass can be empty

        numba.experimental.structref.register(MyStruct)

    ra   )r   rz   r{   r   registerr   StructRefModelr_   )r   s    r   r   r      sL    8 eoo%+EOO+<=>>[&*?*?@k"r   c                 N    ddl m |j                  fd} |      }||fS )a  new(struct_type)

    A jit-code only intrinsic. Used to allocate an **empty** mutable struct.
    The fields are zero-initialized and must be set manually after calling
    the function.

    Example:

        instance = new(MyStruct)
        instance.field = field_value
    r   )imp_dtorc           	      .   | j                   j                            }|j                         }| j                  |      }| j                  j                  || j                  t        j                  |       
| |j                              }| j                  j                  ||      }|j                  ||j                               }|j                  t        j                  |      |       | j!                  |      }	||	_        |	j%                         S rA   )r*   r)   r+   get_abi_sizeofr'   meminfo_alloc_dtorget_constantr   uintpmoduler(   r,   r-   storer   get_null_valuemake_helperr   ru   )r   r   	signaturerR   r1   r2   
alloc_sizer   data_pointerinst_structr   rX   s             r   codegenznew.<locals>.codegen-  s    **9+B+B+DE))+
++J7
++00  j9Wgnni8

 {{//A|Z5J5J5LM 	g,,Z8,G))'9=%$$&&r   ) numba.experimental.jitclass.baser   instance_type)	typingctxr   r   rW   r   rX   s       @@r   r   r     s.     :))I', K
 C<r   c                   F     e Zd ZdZdZe fd       Zd Zed        Z	 xZ
S )StructRefProxyzA PyObject proxy to the Numba allocated structref data structure.

    Notes
    -----

    * Subclasses should not define ``__init__``.
    * Subclasses can override ``__new__``.
    )_typers   c                 B    t         |   |       }||_        ||_        |S )aO  Called by boxing logic, the conversion of Numba internal
        representation into a PyObject.

        Parameters
        ----------
        ty :
            a Numba type instance.
        mi :
            a wrapped MemInfoPointer.

        Returns
        -------
        instance :
             a StructRefProxy instance.
        )super__new__r   rs   )clstyr   rZ   	__class__s       r   r|   zStructRefProxy._numba_box_R  s'    " 7?3'r   c                 p     	  j                   } || S # t        $ r t         fd       }| _         Y %w xY w)zConstruct a new instance of the structref.

        This takes positional-arguments only due to limitation of the compiler.
        The arguments are mapped to ``cls(*args)`` in jit-code.
        c                       |  S rA   r<   )rR   r   s    r   r   z$StructRefProxy.__new__.<locals>.ctors  s    Dz!r   )_StructRefProxy__numba_ctorAttributeErrorr   )r   rR   r   s   `  r   r   zStructRefProxy.__new__h  sL    		$##D T{  	$" "  $C	$s    55c                     | j                   S )znReturns the Numba type instance for this structref instance.

        Subclasses should NOT override.
        )r   )r   s    r   _numba_type_zStructRefProxy._numba_type_z  s     zzr   )r8   r9   r:   r;   	__slots__classmethodr|   r   propertyr   __classcell__)r   s   @r   r   r   G  s:     &I *$  r   r   N)r;   numbar   
numba.corer   r   r   numba.core.datamodelr   r   numba.core.extendingr	   r
   r   r   r   r   r   r   numba.core.typing.templatesr   r   r_   r~   r   r   r   r   r   r<   r   r   <module>r      su     / / 8	 	 	 :D DN('V6 r@.. F ' 'T9 9r   