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