(declare (type ctype type))
(funcall (type-class-negate (type-class-info type)) type))
+(defun-cached (type-singleton-p :hash-function (lambda (type)
+ (logand (type-hash-value type)
+ #xff))
+ :hash-bits 8
+ :values 2
+ :default (values nil t)
+ :init-wrapper !cold-init-forms)
+ ((type eq))
+ (declare (type ctype type))
+ (let ((function (type-class-singleton-p (type-class-info type))))
+ (if function
+ (funcall function type)
+ (values nil nil))))
+
;;; (VALUES-SPECIFIER-TYPE and SPECIFIER-TYPE moved from here to
;;; early-type.lisp by WHN ca. 19990201.)
(aver (eq base+bounds 'real))
'number)))))
+(!define-type-method (number :singleton-p) (type)
+ (let ((low (numeric-type-low type))
+ (high (numeric-type-high type)))
+ (if (and low
+ (eql low high)
+ (eql (numeric-type-complexp type) :real)
+ (member (numeric-type-class type) '(integer rational
+ #!-sb-xc-host float)))
+ (values t (numeric-type-low type))
+ (values nil nil))))
+
;;; Return true if X is "less than or equal" to Y, taking open bounds
;;; into consideration. CLOSED is the predicate used to test the bound
;;; on a closed interval (e.g. <=), and OPEN is the predicate used on
((type= type (specifier-type 'standard-char)) 'standard-char)
(t `(member ,@members)))))
+(!define-type-method (member :singleton-p) (type)
+ (if (eql 1 (member-type-size type))
+ (values t (first (member-type-members type)))
+ (values nil nil)))
+
(!define-type-method (member :simple-subtypep) (type1 type2)
(values (and (xset-subset-p (member-type-xset type1)
(member-type-xset type2))
nconc (loop for code from low upto high
collect (sb!xc:code-char code))))))))
+(!define-type-method (character-set :singleton-p) (type)
+ (let* ((pairs (character-set-type-pairs type))
+ (pair (first pairs)))
+ (if (and (typep pairs '(cons t null))
+ (eql (car pair) (cdr pair)))
+ (values t (code-char (car pair)))
+ (values nil nil))))
+
(!define-type-method (character-set :simple-=) (type1 type2)
(let ((pairs1 (character-set-type-pairs type1))
(pairs2 (character-set-type-pairs type2)))
;; a function which returns a Common Lisp type specifier
;; representing this type
(unparse #'must-supply-this :type function)
-
+ ;; a function which returns T if the CTYPE is inhabited by a single
+ ;; object and, as a value, the object. Otherwise, returns NIL, NIL.
+ ;; The default case (NIL) is interpreted as a function that always
+ ;; returns NIL, NIL.
+ (singleton-p nil :type (or function null))
+
#|
Not used, and not really right. Probably we want a TYPE= alist for the
unary operations, since there are lots of interesting unary predicates that
(:simple-= . type-class-simple-=)
(:complex-= . type-class-complex-=)
(:negate . type-class-negate)
- (:unparse . type-class-unparse))))
+ (:unparse . type-class-unparse)
+ (:singleton-p . type-class-singleton-p))))
(declaim (ftype (function (type-class) type-class) copy-type-class-coldly))
(eval-when (#-sb-xc :compile-toplevel :load-toplevel :execute)