]> git.tdb.fi Git - libs/datafile.git/blob - source/value.h
f809c8fe4d3001cfba4660f45b9e9556a15d3ab8
[libs/datafile.git] / source / value.h
1 /* $Id$
2
3 This file is part of libmspdatafile
4 Copyright © 2006  Mikko Rasa, Mikkosoft Productions
5 Distributed under the LGPL
6 */
7 #ifndef MSP_DATAFILE_VALUE_H_
8 #define MSP_DATAFILE_VALUE_H_
9
10 #include <sstream>
11 #include <string>
12 #include <vector>
13 #include "error.h"
14
15 namespace Msp {
16 namespace DataFile {
17
18 class Value
19 {
20 public:
21         enum Type
22         {
23                 INTEGER,
24                 FLOAT,
25                 STRING,
26                 BOOLEAN,
27                 ENUM
28         };
29
30         Value(Type t, const std::string &d): type(t), data(d) { }
31         template<typename T>
32         T get() const;
33 private:
34         Type type;
35         std::string data;
36 };
37 typedef std::vector<Value> ValueArray;
38
39 template<typename T> struct TypeResolver { static const Value::Type type=Value::ENUM; };
40
41 template<> struct TypeResolver<short>          { static const Value::Type type=Value::INTEGER; };
42 template<> struct TypeResolver<unsigned short> { static const Value::Type type=Value::INTEGER; };
43 template<> struct TypeResolver<int>            { static const Value::Type type=Value::INTEGER; };
44 template<> struct TypeResolver<unsigned>       { static const Value::Type type=Value::INTEGER; };
45 template<> struct TypeResolver<long>           { static const Value::Type type=Value::INTEGER; };
46 template<> struct TypeResolver<unsigned long>  { static const Value::Type type=Value::INTEGER; };
47 template<> struct TypeResolver<float>          { static const Value::Type type=Value::FLOAT; };
48 template<> struct TypeResolver<double>         { static const Value::Type type=Value::FLOAT; };
49 template<> struct TypeResolver<bool>           { static const Value::Type type=Value::BOOLEAN; };
50
51 template<Value::Type T> inline bool check_type(Value::Type) { return false; }
52
53 template<> inline bool check_type<Value::INTEGER>(Value::Type t) { return t==Value::INTEGER; }
54 template<> inline bool check_type<Value::FLOAT>(Value::Type t)   { return t==Value::INTEGER || t==Value::FLOAT; }
55 template<> inline bool check_type<Value::BOOLEAN>(Value::Type t) { return t==Value::BOOLEAN; }
56 template<> inline bool check_type<Value::STRING>(Value::Type t)  { return t==Value::STRING; }
57 template<> inline bool check_type<Value::ENUM>(Value::Type t)    { return t==Value::ENUM; }
58
59 template<typename T>
60 inline T Value::get() const
61 {
62         if(!check_type<TypeResolver<T>::type>(type))
63                 throw TypeError("Type mismatch");
64
65         std::istringstream ss(data);
66         T result;
67         ss>>result;
68         if(ss.fail())
69                 //XXX
70                 throw Exception("Invalid value");
71
72         return result;
73 }
74
75 template<>
76 inline std::string Value::get<std::string>() const
77 {
78         if(type!=STRING)
79                 throw TypeError("Value is not a string");
80         return data;
81 }
82
83 template<>
84 inline const std::string &Value::get<const std::string&>() const
85 {
86         if(type!=STRING)
87                 throw TypeError("Value is not a string");
88         return data;
89 }
90
91 } // namespace DataFile
92 } // namespace Msp
93
94 #endif