forked from g522342435/Configparse
-
Notifications
You must be signed in to change notification settings - Fork 0
/
config.h
199 lines (166 loc) · 5.59 KB
/
config.h
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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
//Config.h
#pragma once
#include <string>
#include <map>
#include <iostream>
#include <fstream>
#include <sstream>
/*
* \brief Generic configuration Class
*
*/
class Config {
// Data
protected:
std::string m_Delimiter; //!< separator between key and value
std::string m_Comment; //!< separator between value and comments
std::map<std::string,std::string> m_Contents; //!< extracted keys and values
std::string mFileName;
typedef std::map<std::string,std::string>::iterator mapi;
typedef std::map<std::string,std::string>::const_iterator mapci;
// Methods
public:
Config(std::string filename,std::string delimiter = "=",std::string comment = "#" );
Config();
template<class T> T Read( const std::string& in_key ) const; //!<Search for key and read value or optional default value, call as read<T>
template<class T> T Read( const std::string& in_key, const T& in_value ) const;
template<class T> bool ReadInto( T& out_var, const std::string& in_key ) const;
template<class T>
bool ReadInto( T& out_var, const std::string& in_key, const T& in_value ) const;
bool FileExist(std::string filename);
void ReadFile(std::string filename,std::string delimiter = "=",std::string comment = "#" );
// Check whether key exists in configuration
bool KeyExists( const std::string& in_key ) const;
// Modify keys and values
template<class T> void Add( const std::string& in_key, const T& in_value );
void Remove( const std::string& in_key );
// Check or change configuration syntax
std::string GetDelimiter() const { return m_Delimiter; }
std::string GetComment() const { return m_Comment; }
std::string SetDelimiter( const std::string& in_s )
{ std::string old = m_Delimiter; m_Delimiter = in_s; return old; }
std::string SetComment( const std::string& in_s )
{ std::string old = m_Comment; m_Comment = in_s; return old; }
void Commit() {
std::ofstream out(this->mFileName);
if (!out) throw File_not_found(this->mFileName);
out << (*this);
out.close();
}
// Write or read configuration
friend std::ostream& operator<<( std::ostream& os, const Config& cf );
friend std::istream& operator>>( std::istream& is, Config& cf );
protected:
template<class T> static std::string T_as_string( const T& t );
template<class T> static T string_as_T( const std::string& s );
static void Trim( std::string& inout_s );
// Exception types
public:
struct File_not_found {
std::string filename;
File_not_found( const std::string& filename_ = std::string() )
: filename(filename_) {} };
struct Key_not_found { // thrown only by T read(key) variant of read()
std::string key;
Key_not_found( const std::string& key_ = std::string() )
: key(key_) {} };
};
/* static */
template<class T> //ostringstream 实现输入值 经过转换输出str
std::string Config::T_as_string( const T& t )
{
// Convert from a T to a string
// Type T must support << operator
std::ostringstream ost;
ost << t;
return ost.str();
}
/* static */
template<class T> // 实现输入值,经过转换输出int
T Config::string_as_T( const std::string& s )
{
// Convert from a string to a T
// Type T must support >> operator
T t;
std::istringstream ist(s);
ist >> t;
return t;
}
/* static */
template<> //模板函数的特例化
inline std::string Config::string_as_T<std::string>( const std::string& s )
{
// Convert from a string to a string
// In other words, do nothing
return s;
}
/* static */
template<>
inline bool Config::string_as_T<bool>( const std::string& s )
{
// Convert from a string to a bool
// Interpret "false", "F", "no", "n", "0" as false
// Interpret "true", "T", "yes", "y", "1", "-1", or anything else as true
bool b = true;
std::string sup = s;
for( std::string::iterator p = sup.begin(); p != sup.end(); ++p )
*p = toupper(*p); // make string all caps
if( sup==std::string("FALSE") || sup==std::string("F") ||
sup==std::string("NO") || sup==std::string("N") ||
sup==std::string("0") || sup==std::string("NONE") )
b = false;
return b;
}
template<class T>
T Config::Read( const std::string& key ) const
{
// Read the value corresponding to key
mapci p = m_Contents.find(key);
if( p == m_Contents.end() ) throw Key_not_found(key);
return string_as_T<T>( p->second );
}
template<class T>
T Config::Read( const std::string& key, const T& value ) const
{
// Return the value corresponding to key or given default value
// if key is not found
mapci p = m_Contents.find(key);
if( p == m_Contents.end() ) return value;
return string_as_T<T>( p->second );
}
template<class T>
bool Config::ReadInto( T& var, const std::string& key ) const
{
// Get the value corresponding to key and store in var
// Return true if key is found
// Otherwise leave var untouched
mapci p = m_Contents.find(key);
bool found = ( p != m_Contents.end() );
if( found ) var = string_as_T<T>( p->second );
return found;
}
template<class T>
bool Config::ReadInto( T& var, const std::string& key, const T& value ) const
{
// Get the value corresponding to key and store in var
// Return true if key is found
// Otherwise set var to given default
mapci p = m_Contents.find(key);
bool found = ( p != m_Contents.end() );
if( found )
var = string_as_T<T>( p->second );
else
var = value;
return found;
}
template<class T>
void Config::Add( const std::string& in_key, const T& value )
{
// Add a key with given value
std::string v = T_as_string( value );
std::string key=in_key;
Trim(key);
Trim(v);
m_Contents[key] = v;
return;
}