Configuration.h
1 //-*-C++-*-
2 /***************************************************************************
3  *
4  * Copyright (C) 2006 by Willem van Straten
5  * Licensed under the Academic Free License version 2.1
6  *
7  ***************************************************************************/
8 
9 // psrchive/Util/units/Configuration.h
10 
11 #ifndef __Configuration_h
12 #define __Configuration_h
13 
14 #include "Reference.h"
15 #include "tostring.h"
16 #include "debug.h"
17 #include "Error.h"
18 
19 #include <vector>
20 #include <iostream>
21 #include <sstream>
22 
24 
27 {
28 public:
29 
30  virtual ~Configuration () {}
31 
33  Configuration (const char* filename = 0);
34 
36  void load (const std::string& filename);
37 
39  class Entry;
40 
42  template<typename T> class Parameter;
43 
45  template<typename T> T get (const std::string& key, T default_value) const;
46 
48  template<typename T> T get (const std::string& key) const;
49 
51  Entry* find (const std::string& key) const;
52 
54  const std::vector<std::string>& get_filenames () const { return filenames; }
55 
57  unsigned get_find_count () const { return find_count; }
58 
59 protected:
60 
62  virtual void load () {}
63 
64  std::vector<std::string> filenames;
65  std::vector<Entry> entries;
66 
67 private:
68 
69  mutable unsigned find_count;
70 };
71 
72 class Configuration::Entry
73 {
74 public:
75  Entry (std::string& k, std::string& v) { key=k; value=v; }
76  std::string key;
77  std::string value;
78 };
79 
80 
81 template<class T>
83 {
84 public:
85 
86  Parameter ()
87  {
88  loader = 0;
89  }
90 
91  Parameter (const T& val)
92  {
93  value = val;
94  loader = 0;
95  }
96 
97  Parameter (const std::string& _key, Configuration* config, T default_value)
98  {
99  key = _key;
100  loader = new DirectLoader (default_value);
101  loader->parameter = this;
102  loader->configuration = config;
103  }
104 
105  Parameter (const std::string& _key, Configuration* config)
106  {
107  key = _key;
108  loader = new DirectLoader;
109  loader->parameter = this;
110  loader->configuration = config;
111  }
112 
113  template<typename Parser>
114  Parameter (const std::string& _key, Configuration* config,
115  Parser* parser, const std::string& default_value)
116  {
117  DEBUG("Configuration::Parameter<T> ctor parser=" << parser);
118  key = _key;
119  loader = new ParseLoader<Parser> (parser, default_value);
120  loader->parameter = this;
121  loader->configuration = config;
122  }
123 
124  ~Parameter ()
125  {
126  if (loader)
127  delete loader;
128  }
129 
131  operator T& ()
132  {
133  if (loader)
134  loader->load();
135 
136  return value;
137  }
138 
140  T get_value () const
141  {
142  if (loader)
143  loader->load();
144 
145  return value;
146  }
147 
149  void set_value (const T& val)
150  {
151  value = val;
152  if (loader)
153  loader->destroy();
154  }
155 
157  T& operator = (const T& t) { set_value(t); return value; }
158 
160  bool operator == (const T& t) const { return get_value() == t; }
161 
163  class Loader;
164 
166  class DirectLoader;
167 
169  template<class P> class ParseLoader;
170 
171  std::string get_key () const { return key; }
172  void set_key (const std::string& _key) { key = _key;}
173 
174  void set_loader (Loader* _load)
175  {
176  DEBUG("Configuration::Parameter::set_loader this=" << this \
177  << " key=" << key << " loader=" << _load);
178 
179  if (loader)
180  loader->destroy();
181  loader = _load;
182  loader->parameter = this;
183  }
184 
185 protected:
186  std::string key;
187  T value;
188  Loader* loader;
189 };
190 
191 template<typename T>
192 class Configuration::Parameter<T>::Loader
193 {
194 public:
195 
196  virtual ~Loader() {}
197 
199  virtual void load () = 0;
200 
201  void destroy ()
202  {
203  parameter->loader = 0;
204  delete this;
205  }
206 
207  Configuration* configuration;
208  Parameter* parameter;
209 };
210 
211 template<typename T>
212 class Configuration::Parameter<T>::DirectLoader : public Loader
213 {
214 public:
215 
216  DirectLoader () { default_value_set = false; }
217 
218  DirectLoader (const T& _default)
219  { default_value = _default; default_value_set = true; }
220 
222  virtual void load ()
223  {
224  Parameter<T>* param = this->parameter;
225  Configuration* config = this->configuration;
226 
227  if (default_value_set)
228  {
229  param->value = config->get (param->key, default_value);
230 
231  DEBUG("Configuration::Parameter<T>::Loader::load key=" << param->key \
232  << " default=" << default_value << " value=" << param->value);
233  }
234  else if (config->find (param->key))
235  {
236  param->value = config->get<T> (param->key);
237 
238  DEBUG("Configuration::Parameter<T>::Loader::load key=" << param->key \
239  << " value=" << param->value);
240  }
241 
242  this->destroy();
243  }
244 
245 protected:
246  T default_value;
247  bool default_value_set;
248 };
249 
250 template<typename T>
251 template<typename P>
252 class Configuration::Parameter<T>::ParseLoader : public Loader
253 {
254 public:
255 
256  ParseLoader (P* _parser, const std::string& _default)
257  {
258  DEBUG("Configuration::Parameter<T>::ParseLoader ctor parser=" << _parser);
259  parser = _parser;
260  default_value = _default;
261  }
262 
264  virtual void load ()
265  {
266  std::string value
267  = this->configuration->get (this->parameter->key, default_value);
268 
269  DEBUG("Configuration::Parameter<T>::ParseLoader::load" \
270  " parser=" << (void*) this->parser.ptr() << \
271  " key=" << this->parameter->key << \
272  " default=" << this->default_value << \
273  " value=" << value);
274 
275  parser->parse( value );
276 
277  DEBUG("Configuration::Parameter<T>::ParseLoader::load parse method called");
278 
279  /* the parser must call either set_value or the assignment operator,
280  which will result in the destruction of this loader */
281  }
282 
283 protected:
284  Reference::To<P> parser;
285  std::string default_value;
286 };
287 
289 template<typename T>
290 T Configuration::get (const std::string& key, T default_value) const
291 {
292  Entry* entry = find (key);
293  if (entry)
294  {
295  DEBUG("Configuration::get found entry->value=" << entry->value);
296  return fromstring<T> (entry->value);
297  }
298 
299  DEBUG("Configuration::get default " << key << " = " << default_value);
300 
301  return default_value;
302 }
303 
305 template<typename T>
306 T Configuration::get (const std::string& key) const
307 {
308  Entry* entry = find (key);
309  if (entry)
310  {
311  DEBUG("Configuration::get found entry->value=" << entry->value);
312  return fromstring<T> (entry->value);
313  }
314  else
315  throw Error (InvalidParam, "Configuration::get", "entry not found");
316 }
317 
318 #endif
319 
bool operator==(const T &t) const
Equality test operator.
Definition: Configuration.h:160
virtual void load()
Load the parameter value.
Definition: Configuration.h:264
unsigned get_find_count() const
Get the number of times that the find method has been called.
Definition: Configuration.h:62
int config()
Call this global method to ensure that configuration is loaded.
A convenient exception handling class.
Definition: Error.h:54
Entry * find(const std::string &key) const
Find the entry with the specified key.
Definition: Configuration.C:82
Stores keyword-value pairs from a configuration file.
Definition: Configuration.h:26
T get(const std::string &key, T default_value) const
Get the value for the specified key.
Definition: Configuration.h:290
void set_value(const T &val)
Set the value.
Definition: Configuration.h:149
Manages Reference::To references to the instance.
Definition: ReferenceAble.h:40
T & operator=(const T &t)
Set equal to T operator.
Definition: Configuration.h:157
const std::vector< std::string > & get_filenames() const
Get the names of the configuration files in the order they were parsed.
Definition: Configuration.h:59
A configurable parameter.
Definition: Configuration.h:47
Configuration(const char *filename=0)
Construct from the specified file.
Definition: Configuration.C:19
T get_value() const
Get a copy of the value.
Definition: Configuration.h:140
virtual void load()
Allow derived types to implement lazy evaluation of file loading.
Definition: Configuration.h:67
Uses an intermediate parser to load from configuration.
Definition: Configuration.h:169

Generated using doxygen 1.8.17