# HG changeset patch
# User Steve Losh <steve@stevelosh.com>
# Date 1551150431 18000
# Node ID 3cf5a5efd686fa5e3cf81fb9c881dbc82324a459
# Parent  ba5b4efb5872324e015061419d854ad2cab060c1
Add iterate (collect-set ...) clause

diff -r ba5b4efb5872 -r 3cf5a5efd686 losh.asd
--- a/losh.asd	Sat Feb 23 22:46:27 2019 -0500
+++ b/losh.asd	Mon Feb 25 22:07:11 2019 -0500
@@ -54,7 +54,9 @@
                                                  "hash-tables"))
 
                  (:file "iterate" :depends-on ("control-flow"
-                                               "sequences"))
+                                               "sequences"
+                                               "iterate-pre"
+                                               "hash-sets"))
                  (:file "gnuplot" :depends-on ("control-flow"
                                                "debugging"
                                                "sequences"))
diff -r ba5b4efb5872 -r 3cf5a5efd686 package.lisp
--- a/package.lisp	Sat Feb 23 22:46:27 2019 -0500
+++ b/package.lisp	Mon Feb 25 22:07:11 2019 -0500
@@ -318,6 +318,7 @@
 (defpackage :losh.iterate
   (:use :cl :iterate :losh.quickutils
     :losh.iterate-pre
+    :losh.hash-sets
     :losh.control-flow ;; always needed because we need a single RECURSIVELY symbol
     :losh.sequences)
   (:documentation "Custom `iterate` drivers and clauses.")
@@ -327,6 +328,7 @@
     :anding
     :averaging
     :collect-hash
+    :collect-set
     :cycling
     :every-nth
     :for-nested
diff -r ba5b4efb5872 -r 3cf5a5efd686 src/iterate.lisp
--- a/src/iterate.lisp	Sat Feb 23 22:46:27 2019 -0500
+++ b/src/iterate.lisp	Mon Feb 25 22:07:11 2019 -0500
@@ -596,6 +596,28 @@
          (with ,hash-table = (make-hash-table :test ,test))
          (setf (gethash ,key ,hash-table) ,value)))))
 
+(defmacro-clause (COLLECT-SET element &optional
+                  INTO var
+                  TEST (test '#'eql))
+  "Collect elements into a hash set at `var`.
+
+  If `var` is omitted the hash set will be returned instead.
+
+  `test` specifies the test used for the hash set.
+
+  Example:
+
+    (iterate (for y :in '(a b a))
+             (collect-set y))
+    ; => {a b}
+
+  "
+  (let ((hash-set (or var iterate::*result-var*)))
+    `(progn
+       (with ,hash-set = (make-hash-set :test ,test))
+       (hset-insert! ,hash-set ,element))))
+
+
 (defmacro-clause (ORING expr &optional INTO var)
   (let ((result (or var iterate::*result-var*)))
     `(reducing ,expr :by #'or :into ,result :initial-value nil)))