Created
October 10, 2023 14:26
-
-
Save Lovesan/52140bc655351e279f30b7a1586cc917 to your computer and use it in GitHub Desktop.
IEnumerable and IReadOnlyCollection<> implementation using bike library
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(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