Skip to content

Instantly share code, notes, and snippets.

@Lovesan
Created October 10, 2023 14:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Lovesan/52140bc655351e279f30b7a1586cc917 to your computer and use it in GitHub Desktop.
Save Lovesan/52140bc655351e279f30b7a1586cc917 to your computer and use it in GitHub Desktop.
IEnumerable and IReadOnlyCollection<> implementation using bike library
(define-dotnet-callable-class (sequence-enumerator
(:interfaces (IEnumerator :object))) ()
"An implementation of IEnumerator<object> for CL sequences."
(parent :initform nil :initarg :parent :reader se-parent)
(seq :initform '() :initarg :sequence :reader se-sequence)
(idx :initform -1 :reader se-index)
(:property current :object :initform nil :reader se-current
:documentation "An element at current enumerator index")
(:defmethod move-next :bool ()
"Advances enumerator position within sequence"
(with-slots (seq idx current) this
(let ((len (length seq)))
(cond ((< idx (1- len))
(incf idx)
(setf current (elt seq idx))
t)
(t (setf current nil))))))
(:defmethod reset :void ()
"Resets enumerator position within sequence"
(with-slots (idx current) this
(setf idx -1 current nil)))
(:defmethod dispose :void ()
"Disposes an enumerator"
(print 'dispose)
(with-slots (parent) this
(setf (slot-value parent 'current-enumerator) nil))
(values)))
(define-dotnet-callable-class (sequence-enumerable-base
(:interfaces System.Collections.IEnumerable)) ()
"An implementation of IEnumerable for lisp sequences"
(seq :initform '() :initarg :sequence :reader se-sequence)
(current-enumerator :initform nil)
(:defmethod get-enumerator System.Collections.IEnumerator ()
"Retrieves an enumerator for the sequence"
(with-slots ((e current-enumerator) seq) this
(or e (setf e (make-instance 'sequence-enumerator
:parent this
:sequence seq))))))
(define-dotnet-callable-class (sequence-enumerable
(:interfaces (IEnumerable :object)))
(sequence-enumerable-base)
"An implementation of generic IEnumerable<> for lisp sequences"
(:defmethod get-enumerator (IEnumerator :object) ()
"Retrieves an enumerator for the sequence"
(call-next-method)))
(define-dotnet-callable-class (read-only-sequence
(:interfaces (IReadOnlyCollection :object)))
(sequence-enumerable)
"An implementation of IReadOnlyCollection<object> for lisp sequences"
(:property count :int :reader seq-count
:documentation "Sequence length"))
(defun read-only-sequence (sequence)
(declare (type sequence sequence))
"Creates a read-only wrapper for a lisp sequence"
(make-instance 'read-only-sequence :sequence sequence))
(defmethod shared-initialize :after ((object read-only-sequence) slot-names
&rest initargs &key sequence &allow-other-keys)
(declare (ignore slot-names initargs))
(with-slots (count) object
(setf count (length sequence))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment