Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#ifndef CONFIG_VALUE_H
#define CONFIG_VALUE_H
#include <string>
#include <iostream>
#include <sstream>
#include <utility>
#include <typeinfo>
// demangle type name
#ifdef __GNUG__
#include <cstdlib>
#include <memory>
#include <cxxabi.h>
// gnu compiler needs to demangle type info
static inline std::string demangle(const char* name)
{
int status = 0;
//enable c++11 by passing the flag -std=c++11 to g++
std::unique_ptr<char, void(*)(void*)> res {
abi::__cxa_demangle(name, NULL, NULL, &status),
std::free
};
return (status==0) ? res.get() : name ;
}
#else
// do nothing if not gnu compiler
static inline std::string demangle(const char* name)
{
return name;
}
#endif
// this helps template specialization in class
template <typename T>
struct __cv_id { typedef T type; };
class ConfigValue
{
public:
friend class ConfigParser;
friend class ConfigObject;
public:
ConfigValue() {}
ConfigValue(const std::string &value);
ConfigValue(std::string &&value);
ConfigValue(const int &value);
ConfigValue(const double &value);
explicit ConfigValue(const char *value);
explicit ConfigValue(const bool &value);
explicit ConfigValue(const long &value);
explicit ConfigValue(const long long &value);
explicit ConfigValue(const unsigned &value);
explicit ConfigValue(const unsigned long &value);
explicit ConfigValue(const unsigned long long &value);
explicit ConfigValue(const float &value);
explicit ConfigValue(const long double &value);
ConfigValue &operator =(const std::string &str);
ConfigValue &operator =(std::string &&str);
bool Bool() const;
char Char() const;
unsigned char UChar() const;
short Short() const;
unsigned short UShort() const;
int Int() const;
unsigned int UInt() const;
long Long() const;
long long LongLong() const;
unsigned long ULong() const;
unsigned long long ULongLong() const;
float Float() const;
double Double() const;
long double LongDouble() const;
const char *c_str() const;
const std::string &String() const {return _value;}
bool IsEmpty() const {return _value.empty();}
operator std::string()
const
{
return _value;
}
bool operator ==(const std::string &rhs)
const
{
return _value == rhs;
}
template<typename T>
T Convert()
const
{
return convert( __cv_id<T>());
}
private:
std::string _value;
template<typename T>
T convert(__cv_id<T> &&)
const
{
std::stringstream iss(_value);
T _cvalue;
if(!(iss >> _cvalue)) {
std::cerr << "Config Value Warning: Undefined value returned, failed to convert "
<< _value
<< " to "
<< demangle(typeid(T).name())
<< std::endl;
}
return _cvalue;
}
ConfigValue convert(__cv_id<ConfigValue>) const {return *this;}
bool convert(__cv_id<bool> &&) const {return (*this).Bool();}
float convert(__cv_id<float> &&) const {return (*this).Float();}
double convert(__cv_id<double> &&) const {return (*this).Double();}
long double convert(__cv_id<long double> &&) const {return (*this).LongDouble();}
std::string convert(__cv_id<std::string> &&) const {return (*this)._value;}
const char* convert(__cv_id<const char*> &&) const {return (*this)._value.c_str();}
};
// show string content of the config value to ostream
std::ostream &operator << (std::ostream &os, const ConfigValue &b);
#endif