(module bag-from-table mzscheme (require "../private/require.ss") (require-class) (require-contracts) (require-etc) (require "../private/method.ss" "../iterator/iterator-interface.ss" "../table/table-interface.ss" "bag-interface.ss" "abstract-bag.ss") (provide/contract [bag-from-table% (implementation?/c bag<%>)] [make-bag-from-table (table/c . -> . bag/c)]) (define-syntax (define/bag stx) (syntax-case stx () [(_ . REST) #'(define/export override bag- . REST)])) (define (make-bag-from-table table) (new bag-from-table% [table table])) (define bag-from-table% (class* abstract-bag% (bag<%>) (super-new) (init-field table) (define/private (copy/table table) (new bag-from-table% [table table])) (define/bag (alist) (send table alist)) (define/bag (elements) (send table keys)) (define/bag (clear) (copy/table (send table clear))) (define/bag (empty?) (send table empty?)) (define/bag (insert/count elem count) (if (positive? count) (send table lookup elem (lambda () (copy/table (send table insert elem count))) (lambda (c) (copy/table (send table insert elem (+ c count))))) this)) (define/bag (iterator) (make-counted-from-indexed (send table iterator))) (define/bag lookup/count (opt-lambda (elem [failure (constant #f)] [success (lambda (e c) e)]) (send table lookup/key elem failure success))) (define/bag (remove/count elem count) (if (positive? count) (send table lookup elem (lambda () (copy/table table)) (lambda (c) (if (<= c count) (copy/table (send table remove elem)) (copy/table (send table insert elem (- c count)))))) this)) (define/bag (select/count) (send table select)) (define/bag (remove/all elem) (copy/table (send table remove elem))) (define/bag (sexp) (send table sexp)) )) (define (make-counted-from-indexed iter) (new counted-from-indexed-iterator% [iter iter])) (define counted-from-indexed-iterator% (class* object% (counted-iterator<%>) (super-new) (init-field iter) (define/private (copy/iter iter) (new counted-from-indexed-iterator% [iter iter])) (define/public (end?) (send iter end?)) (define/public (next) (copy/iter (send iter next))) (define/public (element) (send iter key)) (define/public (count) (send iter element)) )) )