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  if (value.which()==1) {
216  return boost::get<Real>(this->GetImpl()->GenericProp(key));
217  } else if (value.which()==2) {
218  return boost::get<int>(this->GetImpl()->GenericProp(key));
219  }
220  std::ostringstream m("");
221  m << "property '" << key << "' is not numeric";
222  throw GenericPropError(m.str());
223  } else {
224  std::ostringstream m("");
225  m << "unknown property " << key;
226  throw GenericPropError(m.str());
227  }
228  }
229 
230 
232  int GetIntProp(const String& key) const
233  {
234  CheckHandleValidity(*static_cast<const H*>(this));
235  return this->gp_get<int>(key);
236  }
237 
239  bool GetBoolProp(const String& key) const
240  {
241  CheckHandleValidity(*static_cast<const H*>(this));
242  return this->gp_get<bool>(key);
243  }
244 
246  String GetStringProp(const String& key, const String& def) const
247  {
248  CheckHandleValidity(*static_cast<const H*>(this));
249  return this->gp_get<String>(key,def);
250  }
251 
254  Real GetFloatProp(const String& key, Real def) const
255  {
256  CheckHandleValidity(*static_cast<const H*>(this));
257  if(this->HasProp(key)) {
258  GenericPropValue value=GetImpl()->GenericProp(key);
259  if (value.which()==1) {
260  return boost::get<Real>(GetImpl()->GenericProp(key));
261  } else if (value.which()==2) {
262  return boost::get<int>(GetImpl()->GenericProp(key));
263  }
264  std::ostringstream m("");
265  m << "property '" << key << "' is not numeric";
266  throw GenericPropError(m.str());
267  } else {
268  return def;
269  }
270  }
271 
273  int GetIntProp(const String& key, int def) const
274  {
275  CheckHandleValidity(*static_cast<const H*>(this));
276  return this->gp_get<int>(key, def);
277  }
278 
280  bool GetBoolProp(const String& key, bool def) const
281  {
282  CheckHandleValidity(*static_cast<const H*>(this));
283  return this->gp_get<bool>(key, def);
284  }
285 
286  std::map<String,GenericPropValue> GetPropMap() const
287  {
288  CheckHandleValidity(*static_cast<const H*>(this));
289  return this->GetImpl()->GetPropMap();
290  }
291 
292  std::vector<String> GetPropList() const
293  {
294  CheckHandleValidity(*static_cast<const H*>(this));
295  return this->GetImpl()->GetPropList();
296  }
297 };
298 
300 template <typename H>
301 class TEMPLATE_EXPORT GenericPropContainer :
302  public ConstGenericPropContainer<H>
303 {
304 public:
305  void ClearProps()
306  {
307  CheckHandleValidity(*static_cast<const H*>(this));
308  this->GetImpl()->ClearProps();
309  }
310 
312  void SetStringProp(const String& key, const String& value)
313  {
314  CheckHandleValidity(*static_cast<const H*>(this));
315  this->GetImpl()->GenericProp(key)=value;
316  }
317 
319  void SetFloatProp(const String& key, Real value)
320  {
321  CheckHandleValidity(*static_cast<const H*>(this));
322  this->GetImpl()->GenericProp(key)=value;
323  }
324 
326  void SetIntProp(const String& key, int value)
327  {
328  CheckHandleValidity(*static_cast<const H*>(this));
329  this->GetImpl()->GenericProp(key)=value;
330  }
331 
333  void SetBoolProp(const String& key, bool value)
334  {
335  CheckHandleValidity(*static_cast<const H*>(this));
336  this->GetImpl()->GenericProp(key)=value;
337  }
338 
339  void RemoveProp(const String& key)
340  {
341  CheckHandleValidity(*static_cast<const H*>(this));
342  this->GetImpl()->RemoveProp(key);
343  }
344 };
345 
346 
347 } // ns
348 
349 #endif