}
 
 
-// virtual Value::blob()
+// bool cast
+Null   ::operator bool(void) const { return false; }
+Bool   ::operator bool(void) const { return value; }
+SInt   ::operator bool(void) const { return value != 0; }
+UInt   ::operator bool(void) const { return value != 0; }
+Float  ::operator bool(void) const { return value != 0; }
+String ::operator bool(void) const { return true; }
+Enum   ::operator bool(void) const { return static_cast<bool>(*sig->second); }
+Struct ::operator bool(void) const { return true; }
+Array  ::operator bool(void) const { return true; }
+Blob   ::operator bool(void) const { return true; }
+Pointer::operator bool(void) const { return value != 0; }
+
+
+// signed integer cast
+Value  ::operator signed long long (void) const { assert(0); return NULL; }
+Null   ::operator signed long long (void) const { return 0; }
+Bool   ::operator signed long long (void) const { return static_cast<signed long long>(value); }
+SInt   ::operator signed long long (void) const { return value; }
+UInt   ::operator signed long long (void) const { assert(static_cast<signed long long>(value) >= 0); return static_cast<signed long long>(value); }
+Float  ::operator signed long long (void) const { return static_cast<signed long long>(value); }
+Enum   ::operator signed long long (void) const { return static_cast<signed long long>(*sig->second); }
+
+
+// unsigned integer cast
+Value  ::operator unsigned long long (void) const { assert(0); return NULL; }
+Null   ::operator unsigned long long (void) const { return 0; }
+Bool   ::operator unsigned long long (void) const { return static_cast<unsigned long long>(value); }
+SInt   ::operator unsigned long long (void) const { assert(value >= 0); return static_cast<signed long long>(value); }
+UInt   ::operator unsigned long long (void) const { return value; }
+Float  ::operator unsigned long long (void) const { return static_cast<unsigned long long>(value); }
+Enum   ::operator unsigned long long (void) const { return static_cast<unsigned long long>(*sig->second); }
+
+
+// floating point cast
+Value  ::operator double (void) const { assert(0); return NULL; }
+Null   ::operator double (void) const { return 0; }
+Bool   ::operator double (void) const { return static_cast<double>(value); }
+SInt   ::operator double (void) const { return static_cast<double>(value); }
+UInt   ::operator double (void) const { return static_cast<double>(value); }
+Float  ::operator double (void) const { return value; }
+Enum   ::operator double (void) const { return static_cast<unsigned long long>(*sig->second); }
+
+
+// blob cast
 void * Value  ::blob(void) const { assert(0); return NULL; }
 void * Null   ::blob(void) const { return NULL; }
 void * Blob   ::blob(void) const { return buf; }
 void Visitor::visit(UInt *) { assert(0); }
 void Visitor::visit(Float *) { assert(0); }
 void Visitor::visit(String *) { assert(0); }
-void Visitor::visit(Enum *) { assert(0); }
-void Visitor::visit(Bitmask *bitmask) { visit(static_cast<UInt *>(bitmask)); }
+void Visitor::visit(Enum *node) { _visit(node->sig->second); }
+void Visitor::visit(Bitmask *node) { visit(static_cast<UInt *>(node)); }
 void Visitor::visit(Struct *) { assert(0); }
 void Visitor::visit(Array *) { assert(0); }
 void Visitor::visit(Blob *) { assert(0); }
 }
 
 
-Value::operator bool(void) const {
-    const Bool *b = dynamic_cast<const Bool *>(unwrap(this));
-    if (b)
-        return b->value;
-    assert(0);
-    return false;
-}
-
-Value::operator signed long long(void) const {
-    const SInt *sint = dynamic_cast<const SInt *>(unwrap(this));
-    if (sint)
-        return sint->value;
-    const UInt *uint = dynamic_cast<const UInt *>(unwrap(this));
-    if (uint)
-        return uint->value;
-    assert(0);
-    return 0;
-}
-
-Value::operator unsigned long long(void) const {
-    const UInt *uint = dynamic_cast<const UInt *>(unwrap(this));
-    if (uint)
-        return uint->value;
-    assert(0);
-    return 0;
-}
-
-
-Value::operator double(void) const {
-    const Float *fl = dynamic_cast<const Float *>(unwrap(this));
-    assert(fl);
-    return fl->value;
-}
-
 static Null null;
 
 const Value & Value::operator[](size_t index) const {
 
     virtual ~Value() {}
     virtual void visit(Visitor &visitor) = 0;
 
-    operator bool (void) const;
-    operator signed long long (void) const;
-    operator unsigned long long (void) const;
-    operator double (void) const;
+    virtual operator bool (void) const = 0;
+    virtual operator signed long long (void) const;
+    virtual operator unsigned long long (void) const;
+    virtual operator double (void) const;
 
     virtual void *blob(void) const;
     const char *string(void) const;
 class Null : public Value
 {
 public:
+    operator bool (void) const;
+    operator signed long long (void) const;
+    operator unsigned long long (void) const;
+    operator double (void) const;
     void *blob(void) const;
     void visit(Visitor &visitor);
 };
 public:
     Bool(bool _value) : value(_value) {}
 
+    operator bool (void) const;
+    operator signed long long (void) const;
+    operator unsigned long long (void) const;
+    operator double (void) const;
     void visit(Visitor &visitor);
 
     bool value;
 public:
     SInt(signed long long _value) : value(_value) {}
 
+    operator bool (void) const;
+    operator signed long long (void) const;
+    operator unsigned long long (void) const;
+    operator double (void) const;
     void visit(Visitor &visitor);
 
     signed long long value;
 public:
     UInt(unsigned long long _value) : value(_value) {}
 
+    operator bool (void) const;
+    operator signed long long (void) const;
+    operator unsigned long long (void) const;
+    operator double (void) const;
     void visit(Visitor &visitor);
 
     unsigned long long value;
 public:
     Float(double _value) : value(_value) {}
 
+    operator bool (void) const;
+    operator signed long long (void) const;
+    operator unsigned long long (void) const;
+    operator double (void) const;
     void visit(Visitor &visitor);
 
     double value;
 public:
     String(std::string _value) : value(_value) {}
 
+    operator bool (void) const;
     void visit(Visitor &visitor);
 
     std::string value;
 
     Enum(const Signature *_sig) : sig(_sig) {}
 
+    operator bool (void) const;
+    operator signed long long (void) const;
+    operator unsigned long long (void) const;
+    operator double (void) const;
     void visit(Visitor &visitor);
 
     const Signature *sig;
     Struct(Signature *_sig) : sig(_sig), members(_sig->member_names.size()) { }
     ~Struct();
 
+    operator bool (void) const;
     void visit(Visitor &visitor);
 
     const Signature *sig;
     Array(size_t len) : values(len) {}
     ~Array();
 
+    operator bool (void) const;
     void visit(Visitor &visitor);
 
     std::vector<Value *> values;
 
     ~Blob();
 
+    operator bool (void) const;
     void *blob(void) const;
     void visit(Visitor &visitor);
 
 public:
     Pointer(unsigned long long value) : UInt(value) {}
 
+    operator bool (void) const;
     void *blob(void) const;
     void visit(Visitor &visitor);
 };