Skip to content

Commit 7863199

Browse files
committed
Add copy-instance, and allow metadata to work with it
Also make compare work for fset
1 parent 78fb68b commit 7863199

File tree

5 files changed

+54
-0
lines changed

5 files changed

+54
-0
lines changed

src/mixins/meta.lisp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,15 @@ look past weak pointers if they exist"
3434
(when table
3535
(let ((value (gethash key table)))
3636
(if (tg:weak-pointer-p value) (tg:weak-pointer-value value) value)))))
37+
38+
;; We need a custom copy for the meta-object
39+
40+
(defmethod geb.utils:copy-instance ((object meta-mixin) &rest initargs
41+
&key &allow-other-keys)
42+
(declare (ignorable initargs))
43+
(let ((new-object (call-next-method))
44+
(table (gethash object (meta object))))
45+
(when table
46+
(setf (gethash new-object (meta object)) ; should point to the same table
47+
table))
48+
new-object))

src/mixins/mixins.lisp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,11 @@
6666
;; I should implement it for arrays as well!
6767
(defmethod obj-equalp ((obj1 t) (obj2 t))
6868
(equalp obj1 obj2))
69+
70+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
71+
;; Fset comparisons
72+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
73+
74+
(defmethod fset:compare ((x direct-pointwise-mixin) (y direct-pointwise-mixin))
75+
(fset:compare (to-pointwise-list x)
76+
(to-pointwise-list y)))

src/util/package.lisp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ used throughout the GEB codebase"
1212
(muffle-package-variance pax:macro)
1313
(subclass-responsibility pax:function)
1414
(shallow-copy-object pax:function)
15+
(copy-instance pax:generic-function)
1516
(make-pattern pax:macro)
1617
(number-to-digits pax:function)
1718
(digit-to-under pax:function)

src/util/utils.lisp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,34 @@ if wanted
6969
copy))
7070

7171

72+
;; from
73+
;; https://stackoverflow.com/questions/11067899/is-there-a-generic-method-for-cloning-clos-objects
74+
75+
;; Don't need it to be an object on non standard-classes for this
76+
;; project, if so, we can promote it to the old form of being a
77+
;; defgeneric.
78+
79+
(defmethod copy-instance ((object standard-object) &rest initargs &key &allow-other-keys)
80+
"Makes and returns a shallow copy of OBJECT.
81+
82+
An uninitialized object of the same class as OBJECT is allocated by
83+
calling ALLOCATE-INSTANCE. For all slots returned by
84+
CLASS-SLOTS, the returned object has the
85+
same slot values and slot-unbound status as OBJECT.
86+
87+
REINITIALIZE-INSTANCE is called to update the copy with INITARGS."
88+
(let* ((class (class-of object))
89+
(copy (allocate-instance class)))
90+
(dolist (slot (c2mop:class-slots class))
91+
;; moved the mapcar into a let, as allocation wise, CCL
92+
;; preformed better this way.
93+
(let ((slot-name (c2mop:slot-definition-name slot)))
94+
(when (slot-boundp object slot-name)
95+
(setf (slot-value copy slot-name)
96+
(slot-value object slot-name)))))
97+
(values
98+
(apply #'reinitialize-instance copy initargs))))
99+
72100
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
73101
;; Numeric Utilities
74102
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

test/meta.lisp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@
99
(meta-insert obj :a 2)
1010
(is = (meta-lookup obj :a) 2)))
1111

12+
(define-test copying-meta-data-works :parent geb-meta
13+
(let ((obj (make-instance 'mixin-test)))
14+
(meta-insert obj :a 2)
15+
(is = (meta-lookup (geb.utils:copy-instance obj) :a) 2)))
16+
1217
#+nil
1318
(define-test weak-pointers-work :parent geb-meta
1419
(tg:gc :full t)

0 commit comments

Comments
 (0)