OpenStructure
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
generic_property.hh
Go to the documentation of this file.
1 //------------------------------------------------------------------------------
2 // This file is part of the OpenStructure project <www.openstructure.org>
3 //
4 // Copyright (C) 2008-2011 by the OpenStructure authors
5 //
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License as published by the Free
8 // Software Foundation; either version 3.0 of the License, or (at your option)
9 // any later version.
10 // This library is distributed in the hope that it will be useful, but WITHOUT
11 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
13 // details.
14 //
15 // You should have received a copy of the GNU Lesser General Public License
16 // along with this library; if not, write to the Free Software Foundation, Inc.,
17 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 //------------------------------------------------------------------------------
19 #ifndef OST_GENETRIC_PROPERTY_HH
20 #define OST_GENETRIC_PROPERTY_HH
21 
22 /*
23  usage:
24 
25  the impl is derived from GenericPropContainerImpl
26 
27  the handle is derived from GenericPropContainer, and then has the
28  setter and getter methods for String, Real, int and bool mapping
29 */
30 
31 #include <sstream>
32 #include <map>
33 #include <vector>
34 #include <boost/variant.hpp>
35 
36 #include <ost/module_config.hh>
37 #include <ost/invalid_handle.hh>
38 #include <ost/message.hh>
39 
40 namespace ost {
41 
42 struct DLLEXPORT GenericPropError: public Error
43 {
45  Error(m)
46  {}
47 };
48 
49 typedef boost::variant<String, Real, int, bool> GenericPropValue;
50 
52 class TEMPLATE_EXPORT GenericPropContainerImpl
53 {
54  typedef std::map<String,GenericPropValue> PropertyMap;
55 
56 public:
57  GenericPropContainerImpl(): map_(NULL) {}
59  {
60  if (map_) {
61  delete map_;
62  }
63  }
65  map_(rhs.map_ ? new PropertyMap(*rhs.map_) : NULL)
66  { }
67 
69  {
70  this->Assign(r);
71  return *this;
72  }
73 
74  GenericPropValue& GenericProp(const String& key)
75  {
76  if (!map_) {
77  map_=new PropertyMap;
78  }
79  return (*map_)[key];
80  }
81 
82  const GenericPropValue& GenericProp(const String& key) const
83  {
84  if (!map_) {
85  map_=new PropertyMap;
86  }
87  return (*map_)[key];
88  }
89 
90  bool HasProp(const String& key) const
91  {
92  return map_ && map_->find(key) != map_->end();
93  }
94 
95  void ClearProps()
96  {
97  if (map_) {
98  map_->clear();
99  }
100  }
101 
102  void RemoveProp(const String& key)
103  {
104  if (map_) {
105  map_->erase(key);
106  }
107  }
108 
109  void Assign(const GenericPropContainerImpl& impl)
110  {
111  if (impl.map_) {
112  if (!map_) {
113  map_=new PropertyMap(*impl.map_);
114  } else {
115  *map_=*impl.map_;
116  }
117  } else {
118  this->ClearProps();
119  }
120  }
121 
122  PropertyMap GetPropMap() const
123  {
124  if (!map_) {
125  map_=new PropertyMap;
126  }
127  return *map_;
128  }
129 
130  std::vector<String> GetPropList() const
131  {
132  std::vector<String> prop_list;
133  if (map_) {
134  PropertyMap::const_iterator i;
135  for (i=map_->begin(); i!=map_->end(); ++i) {
136  prop_list.push_back(i->first);
137  }
138  }
139  return prop_list;
140  }
141 
142 private:
143  mutable PropertyMap* map_;
144 };
145 
146 template <typename H>
147 class TEMPLATE_EXPORT ConstGenericPropContainer {
148 protected:
149 
150  template<typename T>
151  T gp_get(const String& key) const {
152  if(HasProp(key)) {
153  return boost::get<T>(GetImpl()->GenericProp(key));
154  } else {
155  std::ostringstream m("");
156  m << "unknown property " << key;
157  throw GenericPropError(m.str());
158  }
159  }
160 
161  template<typename T>
162  T gp_get(const String& key, const T& def) const {
163  if(HasProp(key)) {
164  return boost::get<T>(GetImpl()->GenericProp(key));
165  }
166  return def;
167  }
169  {
170  return static_cast<H*>(this)->GpImpl();
171  }
172 
173  const GenericPropContainerImpl* GetImpl() const
174  {
175  return static_cast<const H*>(this)->GpImpl();
176  }
177 
178 public:
180  bool HasProp(const String& key) const {
181  CheckHandleValidity(*static_cast<const H*>(this));
182  return this->GetImpl()->HasProp(key);
183  }
184 
192  String GetPropAsString(const String& key) const
193  {
194  CheckHandleValidity(*static_cast<const H*>(this));
195  if(!HasProp(key)) return "";
196  std::ostringstream rep("");
197  rep << this->GetImpl()->GenericProp(key);
198  return rep.str();
199  }
200 
202  String GetStringProp(const String& key) const
203  {
204  CheckHandleValidity(*static_cast<const H*>(this));
205  return this->gp_get<String>(key);
206  }
207 
210  Real GetFloatProp(const String& key) const
211  {
212  CheckHandleValidity(*static_cast<const H*>(this));
213  if(HasProp(key)) {
214  GenericPropValue value=this->GetImpl()->GenericProp(key);
215  switch (value.which()) {
216  case 1:
217  return boost::get<Real>(value);
218  case 2:
219  return static_cast<Real>(boost::get<int>(value));
220  case 3:
221  return static_cast<Real>(boost::get<bool>(value));
222  }
223  std::ostringstream m("");
224  m << "property '" << key << "' is not numeric";
225  throw GenericPropError(m.str());
226  }
227  std::ostringstream m("");
228  m << "unknown property " << key;
229  throw GenericPropError(m.str());
230  }
232  int GetIntProp(const String& key) const
233  {
234  CheckHandleValidity(*static_cast<const H*>(this));
235  if (HasProp(key)){
236  GenericPropValue value=this->GetImpl()->GenericProp(key);
237  switch (value.which()) {
238  case 2:
239  return boost::get<int>(value);
240  case 3:
241  return boost::get<bool>(value);
242  }
243  std::ostringstream m("");
244  m << "property '" << key << "' is not integral";
245  throw GenericPropError(m.str());
246  }
247  std::ostringstream m("");
248  m << "unknown property " << key;
249  throw GenericPropError(m.str());
250  }
251 
253  bool GetBoolProp(const String& key) const
254  {
255  CheckHandleValidity(*static_cast<const H*>(this));
256  return this->gp_get<bool>(key);
257  }
258 
260  String GetStringProp(const String& key, const String& def) const
261  {
262  CheckHandleValidity(*static_cast<const H*>(this));
263  return this->gp_get<String>(key,def);
264  }
265 
268  Real GetFloatProp(const String& key, Real def) const
269  {
270  CheckHandleValidity(*static_cast<const H*>(this));
271  if(this->HasProp(key)) {
272  GenericPropValue value=GetImpl()->GenericProp(key);
273  switch (value.which()) {
274  case 1:
275  return boost::get<Real>(value);
276  case 2:
277  return static_cast<Real>(boost::get<int>(value));
278  case 3:
279  return static_cast<Real>(boost::get<bool>(value));
280  }
281  std::ostringstream m("");
282  m << "property '" << key << "' is not numeric";
283  throw GenericPropError(m.str());
284  }
285  return def;
286  }
287 
289  int GetIntProp(const String& key, int def) const
290  {
291  CheckHandleValidity(*static_cast<const H*>(this));
292  if(this->HasProp(key)) {
293  GenericPropValue value=GetImpl()->GenericProp(key);
294  switch (value.which()) {
295  case 2:
296  return boost::get<int>(value);
297  case 3:
298  return static_cast<int>(boost::get<bool>(value));
299  }
300  std::ostringstream m("");
301  m << "property '" << key << "' is not integral";
302  throw GenericPropError(m.str());
303  }
304  return def;
305  }
306 
308  bool GetBoolProp(const String& key, bool def) const
309  {
310  CheckHandleValidity(*static_cast<const H*>(this));
311  return this->gp_get<bool>(key, def);
312  }
313 
314  std::map<String,GenericPropValue> GetPropMap() const
315  {
316  CheckHandleValidity(*static_cast<const H*>(this));
317  return this->GetImpl()->GetPropMap();
318  }
319 
320  std::vector<String> GetPropList() const
321  {
322  CheckHandleValidity(*static_cast<const H*>(this));
323  return this->GetImpl()->GetPropList();
324  }
325 };
326 
328 template <typename H>
329 class TEMPLATE_EXPORT GenericPropContainer :
330  public ConstGenericPropContainer<H>
331 {
332 public:
333  void ClearProps()
334  {
335  CheckHandleValidity(*static_cast<const H*>(this));
336  this->GetImpl()->ClearProps();
337  }
338 
340  void SetStringProp(const String& key, const String& value)
341  {
342  CheckHandleValidity(*static_cast<const H*>(this));
343  this->GetImpl()->GenericProp(key)=value;
344  }
345 
347  void SetFloatProp(const String& key, Real value)
348  {
349  CheckHandleValidity(*static_cast<const H*>(this));
350  this->GetImpl()->GenericProp(key)=value;
351  }
352 
354  void SetIntProp(const String& key, int value)
355  {
356  CheckHandleValidity(*static_cast<const H*>(this));
357  this->GetImpl()->GenericProp(key)=value;
358  }
359 
361  void SetBoolProp(const String& key, bool value)
362  {
363  CheckHandleValidity(*static_cast<const H*>(this));
364  this->GetImpl()->GenericProp(key)=value;
365  }
366 
367  void RemoveProp(const String& key)
368  {
369  CheckHandleValidity(*static_cast<const H*>(this));
370  this->GetImpl()->RemoveProp(key);
371  }
372 };
373 
374 
375 } // ns
376 
377 #endif