OpenStructure
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 <exception>
32 #include <sstream>
33 #include <map>
34 #include <vector>
35 #include <boost/variant.hpp>
36 
37 #include <ost/module_config.hh>
38 #include <ost/invalid_handle.hh>
39 
40 namespace ost {
41 
42 struct TEMPLATE_EXPORT GenericPropError: public std::exception
43 {
45  m_(m)
46  {}
47  virtual ~GenericPropError() throw() {}
48  virtual const char* what() const throw() {
49  return m_.c_str();
50  }
52 };
53 
54 typedef boost::variant<String, Real, int, bool> GenericPropValue;
55 
57 class TEMPLATE_EXPORT GenericPropContainerImpl
58 {
59  typedef std::map<String,GenericPropValue> PropertyMap;
60 
61 public:
62  GenericPropContainerImpl(): map_(NULL) {}
64  {
65  if (map_) {
66  delete map_;
67  }
68  }
70  map_(rhs.map_ ? new PropertyMap(*rhs.map_) : NULL)
71  { }
72 
74  {
75  this->Assign(r);
76  return *this;
77  }
78 
79  GenericPropValue& GenericProp(const String& key)
80  {
81  if (!map_) {
82  map_=new PropertyMap;
83  }
84  return (*map_)[key];
85  }
86 
87  const GenericPropValue& GenericProp(const String& key) const
88  {
89  if (!map_) {
90  map_=new PropertyMap;
91  }
92  return (*map_)[key];
93  }
94 
95  bool HasProp(const String& key) const
96  {
97  return map_ && map_->find(key) != map_->end();
98  }
99 
100  void ClearProps()
101  {
102  if (map_) {
103  map_->clear();
104  }
105  }
106 
107  void RemoveProp(const String& key)
108  {
109  if (map_) {
110  map_->erase(key);
111  }
112  }
113 
114  void Assign(const GenericPropContainerImpl& impl)
115  {
116  if (impl.map_) {
117  if (!map_) {
118  map_=new PropertyMap(*impl.map_);
119  } else {
120  *map_=*impl.map_;
121  }
122  } else {
123  this->ClearProps();
124  }
125  }
126 
127  PropertyMap GetPropMap() const
128  {
129  if (!map_) {
130  map_=new PropertyMap;
131  }
132  return *map_;
133  }
134 
135  std::vector<String> GetPropList() const
136  {
137  std::vector<String> prop_list;
138  if (map_) {
139  PropertyMap::const_iterator i;
140  for (i=map_->begin(); i!=map_->end(); ++i) {
141  prop_list.push_back(i->first);
142  }
143  }
144  return prop_list;
145  }
146 
147 private:
148  mutable PropertyMap* map_;
149 };
150 
151 template <typename H>
152 class TEMPLATE_EXPORT ConstGenericPropContainer {
153 protected:
154 
155  template<typename T>
156  T gp_get(const String& key) const {
157  if(HasProp(key)) {
158  return boost::get<T>(GetImpl()->GenericProp(key));
159  } else {
160  std::ostringstream m("");
161  m << "unknown property " << key;
162  throw GenericPropError(m.str());
163  }
164  }
165 
166  template<typename T>
167  T gp_get(const String& key, const T& def) const {
168  if(HasProp(key)) {
169  return boost::get<T>(GetImpl()->GenericProp(key));
170  }
171  return def;
172  }
174  {
175  return static_cast<H*>(this)->GpImpl();
176  }
177 
178  const GenericPropContainerImpl* GetImpl() const
179  {
180  return static_cast<const H*>(this)->GpImpl();
181  }
182 
183 public:
185  bool HasProp(const String& key) const {
186  CheckHandleValidity(*static_cast<const H*>(this));
187  return this->GetImpl()->HasProp(key);
188  }
189 
197  String GetPropAsString(const String& key) const
198  {
199  CheckHandleValidity(*static_cast<const H*>(this));
200  if(!HasProp(key)) return "";
201  std::ostringstream rep("");
202  rep << this->GetImpl()->GenericProp(key);
203  return rep.str();
204  }
205 
207  String GetStringProp(const String& key) const
208  {
209  CheckHandleValidity(*static_cast<const H*>(this));
210  return this->gp_get<String>(key);
211  }
212 
215  Real GetFloatProp(const String& key) const
216  {
217  CheckHandleValidity(*static_cast<const H*>(this));
218  if(HasProp(key)) {
219  GenericPropValue value=this->GetImpl()->GenericProp(key);
220  if (value.which()==1) {
221  return boost::get<Real>(this->GetImpl()->GenericProp(key));
222  } else if (value.which()==2) {
223  return boost::get<int>(this->GetImpl()->GenericProp(key));
224  }
225  std::ostringstream m("");
226  m << "property '" << key << "' is not numeric";
227  throw GenericPropError(m.str());
228  } else {
229  std::ostringstream m("");
230  m << "unknown property " << key;
231  throw GenericPropError(m.str());
232  }
233  }
234 
235 
237  int GetIntProp(const String& key) const
238  {
239  CheckHandleValidity(*static_cast<const H*>(this));
240  return this->gp_get<int>(key);
241  }
242 
244  bool GetBoolProp(const String& key) const
245  {
246  CheckHandleValidity(*static_cast<const H*>(this));
247  return this->gp_get<bool>(key);
248  }
249 
251  String GetStringProp(const String& key, const String& def) const
252  {
253  CheckHandleValidity(*static_cast<const H*>(this));
254  return this->gp_get<String>(key,def);
255  }
256 
259  Real GetFloatProp(const String& key, Real def) const
260  {
261  CheckHandleValidity(*static_cast<const H*>(this));
262  if(this->HasProp(key)) {
263  GenericPropValue value=GetImpl()->GenericProp(key);
264  if (value.which()==1) {
265  return boost::get<Real>(GetImpl()->GenericProp(key));
266  } else if (value.which()==2) {
267  return boost::get<int>(GetImpl()->GenericProp(key));
268  }
269  std::ostringstream m("");
270  m << "property '" << key << "' is not numeric";
271  throw GenericPropError(m.str());
272  } else {
273  return def;
274  }
275  }
276 
278  int GetIntProp(const String& key, int def) const
279  {
280  CheckHandleValidity(*static_cast<const H*>(this));
281  return this->gp_get<int>(key, def);
282  }
283 
285  bool GetBoolProp(const String& key, bool def) const
286  {
287  CheckHandleValidity(*static_cast<const H*>(this));
288  return this->gp_get<bool>(key, def);
289  }
290 
291  std::map<String,GenericPropValue> GetPropMap() const
292  {
293  CheckHandleValidity(*static_cast<const H*>(this));
294  return this->GetImpl()->GetPropMap();
295  }
296 
297  std::vector<String> GetPropList() const
298  {
299  CheckHandleValidity(*static_cast<const H*>(this));
300  return this->GetImpl()->GetPropList();
301  }
302 };
303 
305 template <typename H>
306 class TEMPLATE_EXPORT GenericPropContainer :
307  public ConstGenericPropContainer<H>
308 {
309 public:
310  void ClearProps()
311  {
312  CheckHandleValidity(*static_cast<const H*>(this));
313  this->GetImpl()->ClearProps();
314  }
315 
317  void SetStringProp(const String& key, const String& value)
318  {
319  CheckHandleValidity(*static_cast<const H*>(this));
320  this->GetImpl()->GenericProp(key)=value;
321  }
322 
324  void SetFloatProp(const String& key, Real value)
325  {
326  CheckHandleValidity(*static_cast<const H*>(this));
327  this->GetImpl()->GenericProp(key)=value;
328  }
329 
331  void SetIntProp(const String& key, int value)
332  {
333  CheckHandleValidity(*static_cast<const H*>(this));
334  this->GetImpl()->GenericProp(key)=value;
335  }
336 
338  void SetBoolProp(const String& key, bool value)
339  {
340  CheckHandleValidity(*static_cast<const H*>(this));
341  this->GetImpl()->GenericProp(key)=value;
342  }
343 
344  void RemoveProp(const String& key)
345  {
346  CheckHandleValidity(*static_cast<const H*>(this));
347  this->GetImpl()->RemoveProp(key);
348  }
349 };
350 
351 
352 } // ns
353 
354 #endif