]> git.tdb.fi Git - libs/datafile.git/blobdiff - source/value.h
Rewrite the type system
[libs/datafile.git] / source / value.h
index ace18945cbc2ea39eb4bc395cc116c0016b8e7e0..1b12db9a22db5f40e77578199bdfd7817fff4093 100644 (file)
@@ -1,91 +1,67 @@
 /* $Id$
 
 This file is part of libmspdatafile
-Copyright © 2006  Mikko Rasa, Mikkosoft Productions
+Copyright © 2006-2008, 2010  Mikko Rasa, Mikkosoft Productions
 Distributed under the LGPL
 */
+
 #ifndef MSP_DATAFILE_VALUE_H_
 #define MSP_DATAFILE_VALUE_H_
 
 #include <vector>
-#include <msp/strings/lexicalcast.h>
+#include <msp/core/meta.h>
+#include <msp/core/variant.h>
 #include "except.h"
+#include "type.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:
-       Value(Type t, const std::string &d): type(t), data(d) { }
+private:
+       char sig;
+       Variant data;
 
+public:
        template<typename T>
-       Value(T d): type(TypeResolver<T>::type), data(lexical_cast(d)) { }
+       Value(T d):
+               sig(TypeInfo<T>::signature),
+               data(static_cast<typename TypeInfo<T>::Store>(d))
+       { }
+
+       Value(Symbol d): sig(TypeInfo<Symbol>::signature), data(d) { }
 
        template<typename T>
-       T get() const;
+       typename RemoveReference<T>::Type get() const
+       { return get_<typename TypeInfo<T>::Store>(); }
 
-       Type get_type() const { return type; }
-       const std::string &get_raw() const { return data; }
+       char get_signature() const { return sig; }
 private:
-       Type type;
-       std::string data;
+       template<typename T>
+       T get_() const;
 };
 
-typedef std::vector<Value> ValueArray;
-
-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; }
+typedef std::vector<Value> ValueArray __attribute__((deprecated));
 
 template<typename T>
-inline T Value::get() const
+inline T Value::get_() const
 {
-       if(!check_type<TypeResolver<T>::type>(type))
+       if(sig!=TypeInfo<T>::signature)
                throw TypeError("Type mismatch");
 
-       return lexical_cast<T>(data);
+       return data.value<typename TypeInfo<T>::Store>();
 }
 
 template<>
-inline std::string Value::get<std::string>() const
+inline FloatType::Store Value::get_<FloatType::Store>() const
 {
-       if(type!=STRING)
+       if(sig==IntType::signature)
+               return data.value<IntType::Store>();
+       else if(sig!=FloatType::signature)
                throw TypeError("Type mismatch");
-       return data;
-}
 
-template<>
-inline const std::string &Value::get<const std::string&>() const
-{
-       if(type!=STRING)
-               throw TypeError("Type mismatch");
-       return data;
+       return data.value<FloatType::Store>();
 }
 
 } // namespace DataFile