]> git.tdb.fi Git - libs/datafile.git/blobdiff - source/value.h
Add binary data format
[libs/datafile.git] / source / value.h
index f809c8fe4d3001cfba4660f45b9e9556a15d3ab8..fda83e494db884a228036fafdf3f6ba5c3ec9439 100644 (file)
@@ -7,54 +7,61 @@ Distributed under the LGPL
 #ifndef MSP_DATAFILE_VALUE_H_
 #define MSP_DATAFILE_VALUE_H_
 
-#include <sstream>
-#include <string>
 #include <vector>
+#include <msp/strings/lexicalcast.h>
 #include "error.h"
 
 namespace Msp {
 namespace DataFile {
 
+enum Type
+{
+       INTEGER,
+       FLOAT,
+       STRING,
+       BOOLEAN,
+       ENUM
+};
+
+template<typename T> struct TypeResolver       { static const Type type=ENUM; };
+template<> struct TypeResolver<short>          { static const Type type=INTEGER; };
+template<> struct TypeResolver<unsigned short> { static const Type type=INTEGER; };
+template<> struct TypeResolver<int>            { static const Type type=INTEGER; };
+template<> struct TypeResolver<unsigned>       { static const Type type=INTEGER; };
+template<> struct TypeResolver<long>           { static const Type type=INTEGER; };
+template<> struct TypeResolver<unsigned long>  { static const Type type=INTEGER; };
+template<> struct TypeResolver<long long>      { static const Type type=INTEGER; };
+template<> struct TypeResolver<unsigned long long> { static const Type type=INTEGER; };
+template<> struct TypeResolver<float>          { static const Type type=FLOAT; };
+template<> struct TypeResolver<double>         { static const Type type=FLOAT; };
+template<> struct TypeResolver<bool>           { static const Type type=BOOLEAN; };
+template<> struct TypeResolver<std::string>    { static const Type type=STRING; };
+template<typename T> struct TypeResolver<const T>   { static const Type type=TypeResolver<T>::type; };
+template<typename T> struct TypeResolver<T &>       { static const Type type=TypeResolver<T>::type; };
+template<typename T> struct TypeResolver<const T &> { static const Type type=TypeResolver<T>::type; };
+
 class Value
 {
 public:
-       enum Type
-       {
-               INTEGER,
-               FLOAT,
-               STRING,
-               BOOLEAN,
-               ENUM
-       };
-
        Value(Type t, const std::string &d): type(t), data(d) { }
+
+       template<typename T>
+       Value(T d): type(TypeResolver<T>::type), data(lexical_cast(d)) { }
+
        template<typename T>
        T get() const;
+
+       Type get_type() const { return type; }
+       const std::string &get_raw() const { return data; }
 private:
        Type type;
        std::string data;
 };
-typedef std::vector<Value> ValueArray;
-
-template<typename T> struct TypeResolver { static const Value::Type type=Value::ENUM; };
-
-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; }
+typedef std::vector<Value> ValueArray;
 
-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<Type T> inline bool check_type(Type t)  { return t==T; }
+template<> inline bool check_type<FLOAT>(Type t) { return t==INTEGER || t==FLOAT; }
 
 template<typename T>
 inline T Value::get() const
@@ -76,7 +83,7 @@ template<>
 inline std::string Value::get<std::string>() const
 {
        if(type!=STRING)
-               throw TypeError("Value is not a string");
+               throw TypeError("Type mismatch");
        return data;
 }
 
@@ -84,7 +91,7 @@ template<>
 inline const std::string &Value::get<const std::string&>() const
 {
        if(type!=STRING)
-               throw TypeError("Value is not a string");
+               throw TypeError("Type mismatch");
        return data;
 }