! Copyright (C) 2009 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
-USING: kernel accessors sequences byte-arrays bit-arrays math hints sets ;
+USING: kernel accessors sequences byte-arrays bit-arrays math
+math.bitwise hints sets ;
IN: bit-sets
TUPLE: bit-set { table bit-array read-only } ;
M: bit-set clone
table>> clone bit-set boa ;
+
+M: bit-set cardinality
+ table>> bit-array>integer bit-count ;
M: hash-set set-like drop dup hash-set? [ members <hash-set> ] unless ;
M: hash-set clone table>> clone hash-set boa ;
M: hash-set null? table>> assoc-empty? ;
+M: hash-set cardinality table>> assoc-size ;
M: sequence fast-set <hash-set> ;
M: f fast-set drop H{ } clone hash-set boa ;
HELP: null?
{ $values { "set" set } { "?" "a boolean" } }
{ $description "Tests whether the given set is empty. This outputs " { $snippet "t" } " when given a null set of any type." } ;
+
+HELP: cardinality
+{ $values { "set" set } { "n" "a non-negative integer" } }
+{ $description "Returns the number of elements in the set. All sets support this operation." } ;
[ t ] [ f null? ] unit-test
[ f ] [ { 4 } null? ] unit-test
+
+[ 0 ] [ f cardinality ] unit-test
+[ 0 ] [ { } cardinality ] unit-test
+[ 1 ] [ HS{ 1 } cardinality ] unit-test
GENERIC: duplicates ( set -- seq )
GENERIC: all-unique? ( set -- ? )
GENERIC: null? ( set -- ? )
+GENERIC: cardinality ( set -- n )
+
+M: f cardinality drop 0 ;
! Defaults for some methods.
! Override them for efficiency
M: set null? members null? ; inline
+M: set cardinality members length ;
+
M: set set-like drop ; inline
M: set union
M: set subset?
sequence/tester all? ;
-
+
M: set set=
2dup subset? [ swap subset? ] [ 2drop f ] if ;
M: sequence members
[ pruned ] keep like ;
-
+
M: sequence null?
empty? ; inline
+M: sequence cardinality
+ length ;
+
: combine ( sets -- set )
[ f ]
[ [ [ members ] map concat ] [ first ] bi set-like ]