]> git.tdb.fi Git - libs/datafile.git/blobdiff - source/value.h
Type checking in value conversions
[libs/datafile.git] / source / value.h
index dc117e0a7ff03207e73be05748849c0a182f3e0b..be6a7a483f7768849f845051dbe563e9cea97ac9 100644 (file)
@@ -1,6 +1,6 @@
 /*
 This file is part of libmspparser
-Copyright © 2006 Mikko Rasa, Mikkosoft Productions
+Copyright © 2006  Mikko Rasa, Mikkosoft Productions
 Distributed under the LGPL
 */
 #ifndef MSP_PARSER_VALUE_H_
@@ -21,26 +21,70 @@ public:
                INTEGER,
                FLOAT,
                STRING,
-               BOOLEAN
+               BOOLEAN,
+               ENUM
        };
 
        Value(Type t, const std::string &d): type(t), data(d) { }
        template<typename T>
-       T get() const
-       {
-               std::istringstream ss(data);
-               T result;
-               ss>>result;
-               if(ss.fail())
-                       throw TypeError("Type mismatch");
-               return result;
-       }
+       T get() const;
 private:
        Type type;
        std::string data;
 };
 typedef std::vector<Value> ValueArray;
 
+template<typename T> struct TypeResolver { };
+
+template<> struct TypeResolver<short>          { static const Value::Type type=Value::INTEGER; };
+template<> struct TypeResolver<unsigned short> { static const Value::Type type=Value::INTEGER; };
+template<> struct TypeResolver<int>            { static const Value::Type type=Value::INTEGER; };
+template<> struct TypeResolver<unsigned>       { static const Value::Type type=Value::INTEGER; };
+template<> struct TypeResolver<long>           { static const Value::Type type=Value::INTEGER; };
+template<> struct TypeResolver<unsigned long>  { static const Value::Type type=Value::INTEGER; };
+template<> struct TypeResolver<float>          { static const Value::Type type=Value::FLOAT; };
+template<> struct TypeResolver<double>         { static const Value::Type type=Value::FLOAT; };
+template<> struct TypeResolver<bool>           { static const Value::Type type=Value::BOOLEAN; };
+
+template<Value::Type T> inline bool check_type(Value::Type) { return false; }
+
+template<> inline bool check_type<Value::INTEGER>(Value::Type t) { return t==Value::INTEGER; }
+template<> inline bool check_type<Value::FLOAT>(Value::Type t)   { return t==Value::INTEGER || t==Value::FLOAT; }
+template<> inline bool check_type<Value::BOOLEAN>(Value::Type t) { return t==Value::BOOLEAN; }
+template<> inline bool check_type<Value::STRING>(Value::Type t)  { return t==Value::STRING; }
+template<> inline bool check_type<Value::ENUM>(Value::Type t)    { return t==Value::ENUM; }
+
+template<typename T>
+inline T Value::get() const
+{
+       if(!check_type<TypeResolver<T>::type>(type))
+               throw TypeError("Type mismatch");
+
+       std::istringstream ss(data);
+       T result;
+       ss>>result;
+       if(ss.fail())
+               throw ValueError("Invalid value");
+
+       return result;
+}
+
+template<>
+inline std::string Value::get<std::string>() const
+{
+       if(type!=STRING)
+               throw TypeError("Value is not a string");
+       return data;
+}
+
+template<>
+inline const std::string &Value::get<const std::string&>() const
+{
+       if(type!=STRING)
+               throw TypeError("Value is not a string");
+       return data;
+}
+
 } // namespace Parser
 } // namespace Msp