From 5ef75fefaceb6f8de01b7b7c4616699d03cc352d Mon Sep 17 00:00:00 2001
From: liam <liam@a3d8a0fb-c1db-0310-ace7-a616afeb9e30>
Date: Sun, 16 Apr 2006 19:19:51 +0000
Subject: [PATCH] Add slots 'data and 'cl-invalid to 'gsl-data.  This caches
 the CL equivalent to the GSL object and marks if the cache is incoherent,
 respectively.  Incoherence can be marked T (non-specific) or with the
 element(s) that are out of sync.  All functions that modify the C object need
 to mark incoherence.  Improved documentation for the gsl-data class and
 slots.  Added :after argument to defun-gsl.

git-svn-id: svn+ssh://pop/opt/space/mathematics/gsl/trunk@3035 a3d8a0fb-c1db-0310-ace7-a616afeb9e30
---
 data/combination.lisp |  5 ++-
 data/data.lisp        | 92 +++++++++++++++++++++++++++++++------------
 data/matrix.lisp      | 17 +++++++-
 data/permutation.lisp | 13 +++++-
 data/vector.lisp      | 29 +++++++++-----
 interface.lisp        |  9 +++--
 6 files changed, 124 insertions(+), 41 deletions(-)

diff --git a/data/combination.lisp b/data/combination.lisp
index 4c15a68e..ec562eae 100644
--- a/data/combination.lisp
+++ b/data/combination.lisp
@@ -3,7 +3,7 @@
 ; description: Combinations
 ; date:        Sun Mar 26 2006 - 11:51                   
 ; author:      Liam M. Healy                             
-; modified:    Fri Apr 14 2006 - 17:50
+; modified:    Sun Apr 16 2006 - 14:07
 ;********************************************************
 ;;; $Id: $
 
@@ -65,6 +65,7 @@
 (defun-gsl combination-copy
     ((destination gsl-combination-c) (source gsl-combination-c) )
   "gsl_combination_memcpy"
+  :after ((cl-invalidate destination))
   :documentation
   "Copy the elements of the combination @var{src} into the
   combination @var{dest}.  The two combinations must have the same size.")
@@ -111,6 +112,7 @@
 (defun-gsl combination-next ((c gsl-combination-c))
   "gsl_combination_next"
   :c-return-value :success-failure
+  :after ((cl-invalidate c))
   :documentation
   "Advance the combination @var{c} to the next combination
    in lexicographic order and return T.  If no further
@@ -122,6 +124,7 @@
 (defun-gsl combination-previous ((c gsl-combination-c))
   "gsl_combination_prev"
   :c-return-value :success-failure
+  :after ((cl-invalidate c))
   :documentation
   "Step backwards from the combination @var{c} to the
    previous combination in lexicographic order, returning
diff --git a/data/data.lisp b/data/data.lisp
index 74f5c2c2..035316e0 100644
--- a/data/data.lisp
+++ b/data/data.lisp
@@ -3,7 +3,7 @@
 ; description: Using GSL storage.                        
 ; date:        Sun Mar 26 2006 - 16:32                   
 ; author:      Liam M. Healy                             
-; modified:    Fri Apr 14 2006 - 20:14
+; modified:    Sun Apr 16 2006 - 14:00
 ;********************************************************
 ;;; $Id: $
 
@@ -14,8 +14,21 @@
 ;;;;****************************************************************************
 
 (defclass gsl-data ()
-  ((pointer :initarg :pointer :reader pointer)
-   (storage-size :initarg :storage-size :reader storage-size )))
+  ((pointer :initarg :pointer :reader pointer
+	    :documentation "A C pointer to the GSL representation of the data.")
+   (storage-size :initarg :storage-size :reader storage-size)
+   (data :accessor data-cache
+	 :documentation "The Lisp object corresponding to the GSL data.")
+   (cl-invalid
+    :initform t :accessor cl-invalid
+    :documentation
+    "An indication of whether the Lisp object (slot 'data) agrees with the
+     GSL C data.  If NIL, they agree.  If T, they disagree in an unspecified
+     way.  If a list of index sets, those indices disagree and the remainded
+     are correct."))
+  (:documentation
+   "A superclass for all GSL data storage structures, such as vector, matrix,
+   etc."))
 
 (defparameter *print-contents* t)
 
@@ -34,6 +47,8 @@
   (:documentation "An element of the data."))
 
 (defgeneric (setf gsl-aref) (value object &rest indices)
+  (:method :after (value (object gsl-data) &rest indices)
+    (push indices (cl-invalid object)))
   (:documentation "Set an element of the data."))
 
 (export '(write-binary read-binary write-formatted read-formatted))
@@ -156,9 +171,13 @@
       (free ,symbol))))
 
 ;;;;****************************************************************************
-;;;; Getting values
+;;;; Getting values into CL
 ;;;;****************************************************************************
 
+(defun cl-invalidate (&rest objects)
+  (mapc (lambda (obj) (setf (cl-invalid obj) t))
+	objects))
+
 (export 'data)
 (defgeneric data (object &optional destination)
   (:documentation "Extract the values in the object to a CL object.
@@ -168,43 +187,66 @@
    specified.")
   ;; Default method is to make a sequence
   (:method ((object gsl-data) &optional (sequence 'vector))
-	   (let* ((total-size (apply #'* (storage-size object)))
-		  (seq
-		   (case sequence
-		     (list (make-list total-size))
-		     ((nil vector)
-		      (make-array (list total-size)
-				  :element-type (cl-base-type object)))
-		     (t sequence))))
-	     (loop for i from 0
-		   below (min (length seq) total-size)
-		   do (setf (elt seq i) (gsl-aref object i)))
-	     seq)))
+    (if (eq (cl-invalid object) t)
+	;; set everything
+	(let* ((total-size (apply #'* (storage-size object)))
+	       (seq
+		(case sequence
+		  (list (make-list total-size))
+		  ((nil vector)
+		   (make-array (list total-size)
+			       :element-type (cl-base-type object)))
+		  (t sequence))))
+	  (loop for i from 0
+	     below (min (length seq) total-size)
+	     do (setf (elt seq i) (gsl-aref object i)))
+	  seq)
+	;; set selected
+	(let ((seq (data-cache object)))
+	  (mapc (lambda (is)
+		  (let ((i (first is)))
+		    (setf (elt seq i) (gsl-aref object i))))
+		(cl-invalid object))
+	  seq)))
+  ;; Around method looks for cached value and returns it if valid;
+  ;; otherwise computes CL element(s).
+  (:method :around ((object gsl-data) &optional (sequence 'vector))
+	   (declare (ignore sequence))
+	   (when (cl-invalid object)
+	     (setf (data-cache object)
+		   (call-next-method)
+		   (cl-invalid object)
+		   nil))
+	   (data-cache object)))
 
 ;;;;****************************************************************************
-;;;; Setting values
+;;;; Setting values from CL
 ;;;;****************************************************************************
 
 (defgeneric (setf data) (cl-array object)
   (:documentation "Set the values in the object from a CL array.")
   ;; Default method is to read from a sequence
-  (:method
-   (sequence (object gsl-data))
-   (loop for i from 0
-	 below (min (length sequence) (apply #'* (storage-size object)))
-	 do (setf (gsl-aref object i) (elt sequence i)))))
+  (:method (sequence (object gsl-data))
+    (loop for i from 0
+       below (min (length sequence) (apply #'* (storage-size object)))
+       do (setf (gsl-aref object i) (elt sequence i))))
+  (:method :after (source (object gsl-data))
+	   (setf (cl-invalid object) t)))
 
 (export 'set-all)
 (defgeneric set-all (object value)
-  (:documentation "Set all elements to the value."))
+  (:documentation "Set all elements to the value.")
+  (:method :after ((object gsl-data) value) (cl-invalidate object)))
 
 (export 'set-zero)
 (defgeneric set-zero (object)
-  (:documentation "Set all elements to 0."))
+  (:documentation "Set all elements to 0.")
+  (:method :after ((object gsl-data)) (cl-invalidate object)))
 
 (export 'set-identity)
 (defgeneric set-identity (object)
-  (:documentation "Set elements to represent the identity."))
+  (:documentation "Set elements to represent the identity.")
+  (:method :after ((object gsl-data)) (cl-invalidate object)))
 
 (export 'data-valid)
 (defgeneric data-valid (object)
diff --git a/data/matrix.lisp b/data/matrix.lisp
index 2a068936..1a4d8379 100644
--- a/data/matrix.lisp
+++ b/data/matrix.lisp
@@ -3,7 +3,7 @@
 ; description: Matrices
 ; date:        Sun Mar 26 2006 - 11:51                   
 ; author:      Liam M. Healy                             
-; modified:    Fri Apr 14 2006 - 17:49
+; modified:    Sun Apr 16 2006 - 14:04
 ;********************************************************
 ;;; $Id: $
 
@@ -229,6 +229,7 @@ columns, and the physical number of columns in memory is given by
 (defun-gsl matrix-copy
     ((destination gsl-matrix-c) (source gsl-matrix-c))
   "gsl_matrix_memcpy"
+  :after ((cl-invalidate destination))
   :documentation
   "Copy the elements of the matrix @var{source} into the
    matrix @var{destination}.  The two matrices must have the same size.")
@@ -236,6 +237,7 @@ columns, and the physical number of columns in memory is given by
 (defun-gsl matrix-swap
     ((m1 gsl-matrix-c) (m2 gsl-matrix-c))
   "gsl_matrix_swap"
+  :after ((cl-invalidate m1 m2))
   :documentation
   "Exchange the elements of the matrices @var{m1} and
    @var{m2} by copying.  The two matrices must have the same size.")
@@ -260,6 +262,7 @@ columns, and the physical number of columns in memory is given by
 
 (defun-gsl set-row ((matrix gsl-matrix-c) (i :size) (vector gsl-vector-c))
   "gsl_matrix_set_row"
+  :after ((cl-invalidate matrix))
   :documentation
   "Copy the elements of the vector into the
    @var{i}-th row of the matrix.  The length of the vector must be
@@ -267,6 +270,7 @@ columns, and the physical number of columns in memory is given by
 
 (defun-gsl set-column ((matrix gsl-matrix-c) (j :size) (vector gsl-vector-c))
   "gsl_matrix_set_col"
+  :after ((cl-invalidate matrix))
   :documentation
   "Copy the elements of the vector into the @var{j}-th column of the matrix.
   The length of the vector must be the same as the length of the column.")
@@ -280,16 +284,19 @@ columns, and the physical number of columns in memory is given by
 
 (defun-gsl swap-rows ((matrix gsl-matrix-c) (i :size) (j :size))
   "gsl_matrix_swap_rows"
+  :after ((cl-invalidate matrix))
   :documentation
   "Exchange the @var{i}-th and @var{j}-th rows of the matrix in-place.")
 
 (defun-gsl swap-columns ((matrix gsl-matrix-c) (i :size) (j :size))
   "gsl_matrix_swap_columns"
+  :after ((cl-invalidate matrix))
   :documentation
   "Exchange the @var{i}-th and @var{j}-th columns of the matrix in-place.")
 
 (defun-gsl swap-rowcol ((matrix gsl-matrix-c) (i :size) (j :size))
   "gsl_matrix_swap_rowcol"
+  :after ((cl-invalidate matrix))
   :documentation
   "Exchange the @var{i}-th row and @var{j}-th column of the
    matrix in-place.  The matrix must be square for this operation to
@@ -298,6 +305,7 @@ columns, and the physical number of columns in memory is given by
 (defun-gsl matrix-transpose-copy
     ((destination gsl-matrix-c) (source gsl-matrix-c))
   "gsl_matrix_transpose_memcpy"
+  :after ((cl-invalidate destination))
   :documentation
   "Make the destination matrix the transpose of the source matrix
    by copying the elements.  The dimensions of the destination
@@ -305,6 +313,7 @@ columns, and the physical number of columns in memory is given by
 
 (defun-gsl matrix-transpose ((matrix gsl-matrix-c))
   "gsl_matrix_transpose"
+  :after ((cl-invalidate matrix))
   :documentation
   "Replace the matrix by its transpose by copying the elements
    of the matrix in-place.  The matrix must be square for this
@@ -316,6 +325,7 @@ columns, and the physical number of columns in memory is given by
 
 (defun-gsl matrix+ ((a gsl-matrix-c) (b gsl-matrix-c))
   "gsl_matrix_add"
+  :after ((cl-invalidate a))
   :documentation
   "Add the elements of matrix @var{b} to the elements of matrix @var{a},
    @math{a'_i = a_i + b_i}. The two matrices must have the
@@ -323,6 +333,7 @@ columns, and the physical number of columns in memory is given by
 
 (defun-gsl matrix- ((a gsl-matrix-c) (b gsl-matrix-c))
   "gsl_matrix_sub"
+  :after ((cl-invalidate a))
   :documentation
   "Subtract the elements of matrix @var{b} from the elements of matrix
    @var{a}, @math{a'_i = a_i - b_i}. The two matrices must have the
@@ -330,6 +341,7 @@ columns, and the physical number of columns in memory is given by
 
 (defun-gsl matrix* ((a gsl-matrix-c) (b gsl-matrix-c))
   "gsl_matrix_mul_elements"
+  :after ((cl-invalidate a))
   :documentation
   "Multiply the elements of matrix @var{a} by the elements of
   matrix @var{b}, @math{a'(i,j) = a(i,j) * b(i,j)}. The two matrices must have the
@@ -337,6 +349,7 @@ columns, and the physical number of columns in memory is given by
 
 (defun-gsl matrix/ ((a gsl-matrix-c) (b gsl-matrix-c))
   "gsl_matrix_div_elements"
+  :after ((cl-invalidate a))
   :documentation
   "Divide the elements of matrix @var{a} by the elements of
    matrix @var{b}, @math{a'(i,j) = a(i,j) / b(i,j)}. The two matrices must have the
@@ -345,6 +358,7 @@ columns, and the physical number of columns in memory is given by
 (defun-gsl matrix*c
     ((a gsl-matrix-c) (x :double))
   "gsl_matrix_scale"
+  :after ((cl-invalidate a))
   :documentation
   "Multiply the elements of matrix @var{a} by the constant
   factor @var{x}, @math{a'(i,j) = x a(i,j)}.")
@@ -352,6 +366,7 @@ columns, and the physical number of columns in memory is given by
 (defun-gsl matrix+c
     ((a gsl-matrix-c) (x :double))
   "gsl_matrix_add_constant"
+  :after ((cl-invalidate a))
   :documentation
   "Add the constant value @var{x} to the elements of the
   matrix @var{a}, @math{a'(i,j) = a(i,j) + x}.")
diff --git a/data/permutation.lisp b/data/permutation.lisp
index 54899671..e94a2c90 100644
--- a/data/permutation.lisp
+++ b/data/permutation.lisp
@@ -3,7 +3,7 @@
 ; description: Permutations
 ; date:        Sun Mar 26 2006 - 11:51                   
 ; author:      Liam M. Healy                             
-; modified:    Fri Apr 14 2006 - 20:06
+; modified:    Sun Apr 16 2006 - 14:10
 ;********************************************************
 ;;; $Id: $
 
@@ -49,12 +49,14 @@
 (defun-gsl permutation-copy
     ((destination gsl-permutation-c) (source gsl-permutation-c) )
   "gsl_permutation_memcpy"
+  :after ((cl-invalidate destination))
   :documentation
   "Copy the elements of the permutation @var{src} into the
    permutation @var{dest}.  The two permutations must have the same size.")
 
 (defun-gsl permutation-swap ((p gsl-permutation-c) (i :size) (j :size))
   "gsl_permutation_swap"
+  :after ((cl-invalidate p))
   :documentation
   "Exchanges the @var{i}-th and @var{j}-th elements of the
    permutation @var{p}.")
@@ -94,18 +96,21 @@ once.")
 
 (defun-gsl permutation-reverse ((p gsl-permutation-c))
   "gsl_permutation_reverse"
+  :after ((cl-invalidate p))
   :c-return-value :void
   :documentation
   "Reverse the order of the elements of the permutation @var{p}.")
 
 (defun-gsl permutation-inverse ((inv gsl-permutation-c) (p gsl-permutation-c))
   "gsl_permutation_inverse"
+  :after ((cl-invalidate inv))
   :documentation
   "Reverse the order of the elements of the permutation @var{p}.")
 
 (defun-gsl permutation-next ((p gsl-permutation-c))
   "gsl_permutation_next"
   :c-return-value :success-failure
+  :after ((cl-invalidate p))
   :documentation
   "Advance the permutation @var{p} to the next permutation
    in lexicographic order and return T.  If no further
@@ -117,6 +122,7 @@ once.")
 (defun-gsl permutation-previous ((p gsl-permutation-c))
   "gsl_permutation_prev"
   :c-return-value :success-failure
+  :after ((cl-invalidate p))
   :documentation
   "Step backwards from the permutation @var{p} to the
    previous permutation in lexicographic order, returning T.
@@ -143,6 +149,7 @@ once.")
 
 (defun-gsl permute-vector ((p gsl-permutation-c) (v gsl-vector-c))
   "gsl_permute_vector"
+  :after ((cl-invalidate v))
   :documentation
   "Apply the permutation @var{p} to the elements of the
    vector @var{v}, considered as a row-vector acted on by a permutation
@@ -153,6 +160,7 @@ once.")
 
 (defun-gsl permute-vector-inverse ((p gsl-permutation-c) (v gsl-vector-c))
   "gsl_permute_vector_inverse"
+  :after ((cl-invalidate v))
   :documentation
   "Apply the inverse of the permutation @var{p} to the
   elements of the vector @var{v}, considered as a row-vector acted on by
@@ -165,6 +173,7 @@ once.")
 (defun-gsl permutation*
     ((p gsl-permutation-c) (pa gsl-permutation-c) (pb gsl-permutation-c))
   "gsl_permutation_mul"
+  :after ((cl-invalidate p))
   :documentation
   "Combine the two permutations @var{pa} and @var{pb} into a
   single permutation @var{p}, where @math{p = pa . pb}. The permutation
@@ -176,12 +185,14 @@ once.")
 
 (defun-gsl linear-to-canonical ((q gsl-permutation-c) (p gsl-permutation-c))
   "gsl_permutation_linear_to_canonical"
+  :after ((cl-invalidate q))
   :documentation
   "Compute the canonical form of the permutation @var{p} and
    stores it in the output argument @var{q}.")
 
 (defun-gsl canonical-to-linear ((p gsl-permutation-c) (q gsl-permutation-c))
   "gsl_permutation_canonical_to_linear"
+  :after ((cl-invalidate p))
   :documentation
   "Convert a permutation @var{q} in canonical form back into
    linear form storing it in the output argument @var{p}.")
diff --git a/data/vector.lisp b/data/vector.lisp
index b8edc4de..18d13136 100644
--- a/data/vector.lisp
+++ b/data/vector.lisp
@@ -3,7 +3,7 @@
 ; description: Vectors
 ; date:        Sun Mar 26 2006 - 11:51                   
 ; author:      Liam M. Healy                             
-; modified:    Fri Apr 14 2006 - 17:49
+; modified:    Sun Apr 16 2006 - 13:59
 ;********************************************************
 ;;; $Id: $
 
@@ -94,7 +94,9 @@ deallocated with the vector.
 
 (defun-gsl set-basis ((vector gsl-vector-c) (index :size))
   "gsl_vector_set_basis"
-  :c-return-value :void)
+  :documentation "Set the index element to 1.0, and the rest to 0.0."
+  :c-return-value :void
+  :after ((cl-invalidate vector)))
 
 ;;;;****************************************************************************
 ;;;; Views
@@ -166,16 +168,16 @@ vector is given by @var{base}.")
 ;;;; Copying
 ;;;;****************************************************************************
 
-(defun-gsl vector-copy
-    ((destination gsl-vector-c) (source gsl-vector-c) )
+(defun-gsl vector-copy ((destination gsl-vector-c) (source gsl-vector-c))
   "gsl_vector_memcpy"
+  :after ((cl-invalidate destination))
   :documentation
   "Copy the elements of the vector @var{source} into the
    vector @var{destination}.  The two vectors must have the same length.")
 
-(defun-gsl vector-swap
-    ((v gsl-vector-c) (w gsl-vector-c) )
+(defun-gsl vector-swap ((v gsl-vector-c) (w gsl-vector-c))
   "gsl_vector_swap"
+  :after ((cl-invalidate v w))
   :documentation
   "Exchange the elements of the vectors @var{v} and @var{w}
    by copying.  The two vectors must have the same length.")
@@ -186,12 +188,15 @@ vector is given by @var{base}.")
 
 (defun-gsl vector-swap-elements ((vec gsl-vector-c) (i :size) (j :size))
   "gsl_vector_swap_elements"
+  :after ((push (list i) (cl-invalid vec))
+	  (push (list j) (cl-invalid vec)))
   :documentation
   "Exchange the @var{i}-th and @var{j}-th elements of the
    vector @var{vec} in-place.")
 
 (defun-gsl vector-reverse ((vec gsl-vector-c))
   "gsl_vector_reverse"
+  :after ((cl-invalidate vec))
   :documentation
   "Reverse the order of the elements of the vector @var{vec}.")
 
@@ -201,6 +206,7 @@ vector is given by @var{base}.")
 
 (defun-gsl vector+ ((a gsl-vector-c) (b gsl-vector-c))
   "gsl_vector_add"
+  :after ((cl-invalidate a))
   :documentation
   "Add the elements of vector @var{b} to the elements of
 vector @var{a}, @math{a'_i = a_i + b_i}. The two vectors must have the
@@ -208,6 +214,7 @@ same length.")
 
 (defun-gsl vector- ((a gsl-vector-c) (b gsl-vector-c))
   "gsl_vector_sub"
+  :after ((cl-invalidate a))
   :documentation
   "Subtract the elements of vector @var{b} from the elements of
 vector @var{a}, @math{a'_i = a_i - b_i}. The two vectors must have the
@@ -215,6 +222,7 @@ same length.")
 
 (defun-gsl vector* ((a gsl-vector-c) (b gsl-vector-c))
   "gsl_vector_mul"
+  :after ((cl-invalidate a))
   :documentation
   "Multiply the elements of vector @var{a} by the elements of
 vector @var{b}, @math{a'_i = a_i * b_i}. The two vectors must have the
@@ -222,21 +230,22 @@ same length.")
 
 (defun-gsl vector/ ((a gsl-vector-c) (b gsl-vector-c))
   "gsl_vector_div"
+  :after ((cl-invalidate a))
   :documentation
   "Divide the elements of vector @var{a} by the elements of
 vector @var{b}, @math{a'_i = a_i / b_i}. The two vectors must have the
 same length.")
 
-(defun-gsl vector*c
-    ((a gsl-vector-c) (x :double))
+(defun-gsl vector*c ((a gsl-vector-c) (x :double))
   "gsl_vector_scale"
+  :after ((cl-invalidate a))
   :documentation
   "Multiply the elements of vector @var{a} by the constant
 factor @var{x}, @math{a'_i = x a_i}.")
 
-(defun-gsl vector+c
-    ((a gsl-vector-c) (x :double))
+(defun-gsl vector+c ((a gsl-vector-c) (x :double))
   "gsl_vector_add_constant"
+  :after ((cl-invalidate a))
   :documentation
   "Add the constant value @var{x} to the elements of the
 vector @var{a}, @math{a'_i = a_i + x}.")
diff --git a/interface.lisp b/interface.lisp
index b60075eb..6f3adb43 100644
--- a/interface.lisp
+++ b/interface.lisp
@@ -3,7 +3,7 @@
 ; description: Macros to interface GSL functions.
 ; date:        Mon Mar  6 2006 - 22:35                   
 ; author:      Liam M. Healy
-; modified:    Thu Apr  6 2006 - 22:08
+; modified:    Sun Apr 16 2006 - 13:03
 ;********************************************************
 
 (in-package :gsl)
@@ -279,7 +279,7 @@ and a scaling exponent e10, such that the value is val*10^e10."
 (defmacro defun-gsl
     (cl-name arguments gsl-name
      &key documentation return mode (c-return-value :error-code)
-     check-null-pointers method)
+     check-null-pointers method after)
   "Define a CL function that provides an interface to a GSL function.
    If cl-name is :lambda, make a lambda.  Arguments:
      arguments:       a list of input arguments (symbol type) to the GSL function
@@ -295,7 +295,9 @@ and a scaling exponent e10, such that the value is val*10^e10."
                       if a null pointer, signal an error.
      method           Make output a defmethod with the value as the arglist;
                       'arguments should then include explicit mapping of all arguments
-                      to GSL form."
+                      to GSL form.
+     after            Functions to call after the GSL function has been called;
+                      result is discarded."
   (let ((clargs (or method (mapcar #'rst-symbol arguments)))
 	(return-symb-type
 	 (unless (eq c-return-value :return)
@@ -332,6 +334,7 @@ and a scaling exponent e10, such that the value is val*10^e10."
 			  `((check-gsl-status creturn `(,',cl-name))) ; need args
 			  `((check-gsl-status creturn `(,',cl-name ,,@clargs))))))
 	     ,@(check-null-pointers check-null-pointers)
+	     ,@after
 	     (values
 	      ,@(case c-return-value
 		      (:number-of-answers
-- 
GitLab