FLAME  devel
 All Classes Functions Variables Typedefs Enumerations Pages
config.h
1 #ifndef FLAME_CONFIG_H
2 #define FLAME_CONFIG_H
3 
4 #include <stdio.h>
5 
6 #ifdef __cplusplus
7 extern "C" {
8 #endif
9 
10 #ifdef __cplusplus
11 } // extern "C"
12 
13 #include <ostream>
14 #include <vector>
15 #include <map>
16 #include <memory>
17 #include <stdexcept>
18 
19 #include <boost/shared_ptr.hpp>
20 #include <boost/variant.hpp>
21 #include <boost/call_traits.hpp>
22 #include <boost/static_assert.hpp>
23 
24 #include "util.h"
25 
26 namespace detail {
27 // helper to return POD types by value and complex types by const reference
28 template<typename X>
29 struct RT { typedef const X& type; };
30 template<> struct RT<double> { typedef double type; };
31 
32 template<typename V>
33 struct buildval {
34  static inline V op() { return V(); }
35 };
36 template<>
37 struct buildval<double> {
38  static inline double op() { return 0.0; }
39 };
40 
41 // helper to ensure that attempts to call Config::get<T> for unsupported T will fail to compile.
42 template<typename T>
43 struct is_config_value {
44 };
45 #define IS_CONFIG_VALUE(TYPE) \
46 namespace detail {template<> struct is_config_value<TYPE> { typedef TYPE type; };}
47 } // namespace detail
48 IS_CONFIG_VALUE(double)
49 IS_CONFIG_VALUE(std::string)
50 IS_CONFIG_VALUE(std::vector<double>)
51 
66 class Config
67 {
68 public:
70  typedef boost::variant<
71  double,
72  std::vector<double>,
73  std::string,
74  std::vector<Config>
76 
77  typedef std::vector<Config> vector_t;
78 
79  typedef std::map<std::string, value_t> values_t;
80 private:
81  typedef boost::shared_ptr<values_t> values_pointer;
82  typedef boost::shared_ptr<const values_t> const_values_pointer;
83 
84  values_pointer values;
85  const_values_pointer implicit_values;
86 
87  void _cow();
88 public:
90  Config();
93  Config(const Config&);
94  ~Config() {}
96  Config& operator=(const Config&);
97 
101  bool tryGetAny(const std::string& name, value_t& ret) const;
105  const value_t& getAny(const std::string& name) const;
108  void setAny(const std::string& name, const value_t& val);
110  void swapAny(const std::string& name, value_t& val);
111 
121  template<typename T>
122  typename detail::RT<T>::type
123  get(const std::string& name) const {
124  try {
125  return boost::get<typename detail::is_config_value<T>::type>(getAny(name));
126  } catch(boost::bad_get&) {
127  throw key_error(SB()<<"Wrong type for '"<<name<<"'. should be "<<typeid(T).name());
128  }
129  }
139  template<typename T>
140  typename detail::RT<T>::type
141  get(const std::string& name, typename boost::call_traits<T>::param_type def) const {
142  try{
143  return boost::get<typename detail::is_config_value<T>::type>(getAny(name));
144  } catch(boost::bad_get&) {
145  } catch(key_error&) {
146  }
147  return def;
148  }
149 
154  template<typename T>
155  bool
156  tryGet(const std::string& name, T& val) const {
157  value_t ret;
158  if(tryGetAny(name, ret)) {
159  try{
160  val = boost::get<typename detail::is_config_value<T>::type>(ret);
161  return true;
162  } catch(boost::bad_get&) {
163  }
164  }
165  return false;
166  }
167 
174  template<typename T>
175  void set(const std::string& name,
176  typename boost::call_traits<typename detail::is_config_value<T>::type>::param_type val)
177  {
178  _cow();
179  (*values)[name] = val;
180  }
181 
191  template<typename T>
192  void swap(const std::string& name,
193  typename boost::call_traits<typename detail::is_config_value<T>::type>::reference val)
194  {
195  value_t temp = detail::buildval<T>::op();
196  val.swap(boost::get<T>(temp));
197  swapAny(name, temp);
198  //val.swap(boost::get<T>(temp)); // TODO: detect insert, make this a real swap
199  }
200 
202  void swap(Config& c)
203  {
204  // no _cow() here since no value_t are modified
205  values.swap(c.values);
206  implicit_values.swap(c.implicit_values);
207  }
208 
210  void show(std::ostream&, unsigned indent=0) const;
211 
213  typedef values_t::iterator iterator;
215  typedef values_t::const_iterator const_iterator;
216 
218  inline const_iterator begin() const { return values->begin(); }
220  inline const_iterator end() const { return values->end(); }
221 
222  inline void reserve(size_t) {}
224  Config new_scope() const;
225  void push_scope();
226 
227  void flatten();
228 };
229 
230 IS_CONFIG_VALUE(std::vector<Config>);
231 
232 inline
233 std::ostream& operator<<(std::ostream& strm, const Config& c)
234 {
235  c.show(strm);
236  return strm;
237 }
238 
241 {
242  class Pvt;
243  std::auto_ptr<Pvt> priv;
244 public:
246  GLPSParser();
247  ~GLPSParser();
248 
254  void setVar(const std::string& name, const Config::value_t& v);
256  void setPrinter(std::ostream*);
257 
265  Config *parse_file(const char *fname);
274  Config *parse_file(FILE *fp, const char *path=NULL);
282  Config *parse_byte(const char* s, size_t len, const char *path=NULL);
289  Config *parse_byte(const std::string& s, const char *path=NULL);
290 };
291 
293 void GLPSPrint(std::ostream& strm, const Config&);
294 
295 
296 #undef IS_CONFIG_VALUE
297 
298 #endif /* extern "C" */
299 
300 #endif // FLAME_CONFIG_H
values_t::iterator iterator
iterator
Definition: config.h:213
void setVar(const std::string &name, const Config::value_t &v)
Pre-define variable.
Definition: config.cpp:350
STL namespace.
void setPrinter(std::ostream *)
Set output for lexer/parser error messages.
Definition: config.cpp:356
void set(const std::string &name, typename boost::call_traits< typename detail::is_config_value< T >::type >::param_type val)
Definition: config.h:175
Interface to lattice file parser.
Definition: config.h:240
void swap(const std::string &name, typename boost::call_traits< typename detail::is_config_value< T >::type >::reference val)
Definition: config.h:192
GLPSParser()
Construct an empty parser context.
Definition: config.cpp:343
Associative configuration container.
Definition: config.h:66
void show(std::ostream &, unsigned indent=0) const
Print listing of inner scope.
Definition: config.cpp:188
Definition: config.h:26
Config * parse_file(const char *fname)
Open and parse a file.
Definition: config.cpp:362
boost::variant< double, std::vector< double >, std::string, std::vector< Config > > value_t
An individual value (double, double[], string, or Config[])
Definition: config.h:75
const_iterator end() const
one after the last element
Definition: config.h:220
void swap(Config &c)
Exchange entire Config.
Definition: config.h:202
bool tryGet(const std::string &name, T &val) const
Definition: config.h:156
values_t::const_iterator const_iterator
const_iterator
Definition: config.h:215
Config * parse_byte(const char *s, size_t len, const char *path=NULL)
Parse from byte buffer.
Definition: config.cpp:403
const_iterator begin() const
The first element.
Definition: config.h:218