quiero definir un método que se especializará en un objeto de tipo matriz con bytes sin signo de 8 elementos. En sbcl, cuando (make-array x :element-type '(unsigned-byte 8))
la clase de objeto es implementada por SB-KERNEL :: SIMPLE-ARRAY-UNSIGNED-BYTE-8. ¿Existe una forma independiente de implementación de especialización en tipos de matriz de bytes sin signo?En Common Lisp, ¿cómo puedo comprobar el tipo de un objeto en una manera portátil
Respuesta
Utilice un sharpsign-punto para insertar la clase de objeto depende de la implementación en lectura-tiempo:
(defmethod foo ((v #.(class-of (make-array 0 :element-type '(unsigned-byte 8)))))
:unsigned-byte-8-array)
El sharpsign-dot lector macro evalúa el formulario de lectura-tiempo, la determinación de la clase de la matriz. El método estará especializado en la clase que utiliza la implementación de Common Lisp para la matriz.
en cuenta que el argumento :ELEMENT-TYPE
-MAKE-ARRAY
hace algo especial y su comportamiento exacto puede ser un poco sorprendente.
Al usarlo, le está diciendo a Common Lisp que el ARRAY debería poder almacenar elementos de ese tipo de elemento o alguno de sus subtipos.
sistema Lisp The Common entonces devuelve un vector que puede almacenar estos elementos. Puede ser una matriz especializada o una matriz que también puede almacenar elementos más generales.
Aviso: no es una declaración de tipo y que no necesariamente se comprueba en tiempo de compilación o en tiempo de ejecución.
La función UPGRADED-ARRAY-ELEMENT-TYPE
le dice a qué elemento se puede actualizar una matriz.
LispWorks 64 bits:
CL-USER 10 > (upgraded-array-element-type '(unsigned-byte 8))
(UNSIGNED-BYTE 8)
CL-USER 11 > (upgraded-array-element-type '(unsigned-byte 4))
(UNSIGNED-BYTE 4)
CL-USER 12 > (upgraded-array-element-type '(unsigned-byte 12))
(UNSIGNED-BYTE 16)
Así, LispWorks de 64 bits tiene arreglos especiales para 4 y 8 elementos bits. Para elementos de 12 bits, asigna una matriz que puede almacenar elementos de hasta 16 bits.
Generamos una matriz que puede almacenar diez números de hasta 12 bits de:
CL-USER 13 > (make-array 10
:element-type '(unsigned-byte 12)
:initial-element 0)
#(0 0 0 0 0 0 0 0 0 0)
Vamos a comprobar su tipo:
CL-USER 14 > (type-of *)
(SIMPLE-ARRAY (UNSIGNED-BYTE 16) (10))
Es una simple matriz (no ajustable, ningún puntero de relleno) Puede almacenar elementos del tipo (UNSIGNED-BYTE 16)
y sus subtipos. Tiene una longitud de 10 y tiene una dimensión.
En una función normal se puede utilizar etypecase hacer el envío:
El siguiente código no es autónomo sino que debe dar una idea de cómo implementar una función que hace operaciones de punto-sabia aun cuando el para las matrices 3D:
(.* (make-array 3 :element-type 'single-float
:initial-contents '(1s0 2s0 3s0))
(make-array 3 :element-type 'single-float
:initial-contents '(2s0 2s0 3s0)))
Aquí está el código:
(def-generator (point-wise (op rank type) :override-name t)
(let ((name (format-symbol ".~a-~a-~a" op rank type)))
(store-new-function name)
`(defun ,name (a b &optional (b-start (make-vec-i)))
(declare ((simple-array ,long-type ,rank) a b)
(vec-i b-start)
(values (simple-array ,long-type ,rank) &optional))
(let ((result (make-array (array-dimensions b)
:element-type ',long-type)))
,(ecase rank
(1 `(destructuring-bind (x)
(array-dimensions b)
(let ((sx (vec-i-x b-start)))
(do-region ((i) (x))
(setf (aref result i)
(,op (aref a (+ i sx))
(aref b i)))))))
(2 `(destructuring-bind (y x)
(array-dimensions b)
(let ((sx (vec-i-x b-start))
(sy (vec-i-y b-start)))
(do-region ((j i) (y x))
(setf (aref result j i)
(,op (aref a (+ j sy) (+ i sx))
(aref b j i)))))))
(3 `(destructuring-bind (z y x)
(array-dimensions b)
(let ((sx (vec-i-x b-start))
(sy (vec-i-y b-start))
(sz (vec-i-z b-start)))
(do-region ((k j i) (z y x))
(setf (aref result k j i)
(,op (aref a (+ k sz) (+ j sy) (+ i sx))
(aref b k j i))))))))
result))))
#+nil
(def-point-wise-op-rank-type * 1 sf)
(defmacro def-point-wise-functions (ops ranks types)
(let ((specific-funcs nil)
(generic-funcs nil))
(loop for rank in ranks do
(loop for type in types do
(loop for op in ops do
(push `(def-point-wise-op-rank-type ,op ,rank ,type)
specific-funcs))))
(loop for op in ops do
(let ((cases nil))
(loop for rank in ranks do
(loop for type in types do
(push `((simple-array ,(get-long-type type) ,rank)
(,(format-symbol ".~a-~a-~a" op rank type)
a b b-start))
cases)))
(let ((name (format-symbol ".~a" op)))
(store-new-function name)
(push `(defun ,name (a b &optional (b-start (make-vec-i)))
(etypecase a
,@cases
(t (error "The given type can't be handled with a generic
point-wise function."))))
generic-funcs))))
`(progn ,@specific-funcs
,@generic-funcs)))
(def-point-wise-functions (+ - * /) (1 2 3) (ub8 sf df csf cdf))
- 1. Eliminación de un tipo en Common Lisp
- 2. Especificadores de tipo Common Lisp
- 3. Webdevelopment en Common Lisp
- 4. ¿Cómo puedo reutilizar una búsqueda gethash en Common Lisp?
- 5. Asociación en Common Lisp
- 6. Secuencias en Common Lisp?
- 7. Common Lisp: Anexar un plist anidado de manera eficiente
- 8. raspando una tabla HTML en Common Lisp?
- 9. Restablecer el estado en Common Lisp
- 10. Cómo implementar Multi-Threads en Common Lisp
- 11. En common-lisp, ¿cómo puedo insertar un elemento en una lista en contexto?
- 12. Dibujando árboles en Common Lisp
- 13. Common Lisp a Lisp-n?
- 14. Renombrando lambda en Common Lisp
- 15. División entera en Common Lisp?
- 16. Usando un objeto de cadena como una clave hash en Common Lisp
- 17. ¿El mejor framework web en Common-Lisp?
- 18. Predijo Common Lisp
- 19. ¿Cómo obtengo una GUI de common-lisp en Windows?
- 20. ¿Cómo puedo hacer que el constructor de una estructura se evalúe secuencialmente en Common Lisp?
- 21. Cómo reducir el tamaño de un ejecutable Clozure Common Lisp?
- 22. iPhone cómo comprobar el tipo de un objeto?
- 23. ¿Cómo funciona el trabajo de adición en Common Lisp?
- 24. LET versus LET * en Common Lisp
- 25. Desenrolle/argumentos splat en Common Lisp
- 26. Función de persistencia en Common Lisp
- 27. Uso de etiquetas en Common Lisp
- 28. Best Common Lisp IDE
- 29. Introspección de clase en Common Lisp
- 30. definiendo setf-expanders en Common Lisp