copy the relevant portions of self into copy-object. ok if it calls copy on sub-objects.
Defined for each component class of an object with mixin COPYABLE-MIXIN. It should setup its slots as appropriate. This needs to be a seperate method (from COPY-INNER) because it has to be done with a PROGN Method-Combination.
returns a fullfledged copy of self, set-up and ready to go.
return a new, empty version of self
Copy objects with aribtrarily complex substructure. Objects are kept track of in a HashTable, so only one copy is made of each. Things which are EQ in the original (i.e. objects, sublists, etc.) come out EQ in the corresponding places in the copy.
Last pass to make sure everything is in place.
defined for each component class of an object with mixin copyable-mixin. it should setup its slots as appropriate. this needs to be a seperate method (from copy-final) because it has to be done with a progn method-combination.
COPY-SET-SLOT-1 (COPY-OBJECT SLOT-NAME VALUE)
COPY-SLOT-1 (COPY-OBJECT SLOT-NAME ORIGINAL-OBJECT COPY-HTABLE)
DUPLICATE-CLASS-FORMS-COPY (SYMBOL CLASS-NAME ALL-SLOTS SLOT-FORMS)
DUPLICATE-CLASS-FORMS-FINAL-DUPLICATE (SYMBOL CLASS-NAME FINAL-DUPLICATE-FORMS COPY-FORMS?)
DEFCOPY-METHODS (CLASS &KEY COPY SET COPY-ALL SET-ALL)
Put a different face on duplicator-methods's syntax.
DEFINE-COPY-METHOD (NAME &REST BODY)
Ends up as a define-layered-method with special support for copy-specific syntax features.
DEFINE-COPY-PROTOCOL (NAME &OPTIONAL SUPER-PROTOCOLS &REST OPTIONS)
Define a copy protocol, which directly maps to a ContextL layer.
DUPLICATOR-METHODS ((CLASS-NAME &KEY (SYMBOL 'SELF) (COPY-FORMS? *DUPLICATE-CLASS-FORMS-COPY-FORMS?*)) ALL-SLOTS SLOT-FORMS &OPTIONAL FINAL-DUPLICATE-FORMS)
WITH-SLOT-COPYING ((COPY-OBJECT COPY-HTABLE &OPTIONAL (ORIGINAL-OBJECT 'SELF)) &BODY BODY)
DEFINE-COPY-FUNCTION (NAME ARGS &REST OPTIONS)
WITH-COPY-PROTOCOL (NAME &BODY BODY)
Suppose you make an instance of the class foo: (defclass foo () ((test :accessor test :initform #'equal :initarg :test))) (setf *foo* (make-instance 'foo :test #'eql)) Its `test` slot will be set to #'eql: (test *foo*) => #'eql If you want to make a structural clone (for lack of a better term) of `*foo*`, you might try: (setf *new-foo* (make-instance (type-of *foo*))) But `*new-foo*`'s test slot won't be set properly: (test *new-foo*) => #'equal For simple classes, this is no problem but suppose we have a graph from [CL-Graph] and want to make a copy of that: (make-graph (type-of old-graph) :vertex-test (vertex-test old-graph) :vertex-key (vertex-key old-graph) :edge-test (edge-test old-graph) :edge-key (edge-key old-graph) :default-edge-type (default-edge-type old-graph) :default-edge-class (default-edge-class old-graph) :directed-edge-class (directed-edge-class old-graph) :undirected-edge-class (undirected-edge-class old-graph)))) Yuck! Copy-template is a reasonable, though not perfect, solution to this problem; it creates a structural copy of an object such that the copy has all of its initargs correctly set. [CL-Graph]: http://common-lisp.net/projects/cl-graph/
=LAYERED-FUNCTION-DEFINER-FOR-COPY-FINAL-CLASS= (LAYER-ARG69 SELF COPY)
=LAYERED-FUNCTION-DEFINER-FOR-COPY-FINAL= (LAYER-ARG19 SELF COPY)
=LAYERED-FUNCTION-DEFINER-FOR-COPY-INNER-CLASS= (LAYER-ARG24 SELF COPY-OBJECT COPY-HTABLE)
=LAYERED-FUNCTION-DEFINER-FOR-COPY-INNER= (LAYER-ARG13 SELF COPY-OBJECT COPY-HTABLE)
=LAYERED-FUNCTION-DEFINER-FOR-COPY-ONE= (LAYER-ARG4 SELF COPY-HTABLE)
=LAYERED-FUNCTION-DEFINER-FOR-COPY-SELF= (LAYER-ARG9 SELF)
=LAYERED-FUNCTION-DEFINER-FOR-COPY-SLOTS-SLOTS-TO-INITIALIZE= (LAYER-ARG30 SELF)
=LAYERED-FUNCTION-DEFINER-FOR-COPY-THING= (LAYER-ARG0 THING)
Holds a list of copy protocol names
provides method for doing copy that creates a copy on an object. each mixin should provide an copy-inner-class method to copy its slots appropriately.