cartobase  5.0.5
property.h
Go to the documentation of this file.
1 /* This software and supporting documentation are distributed by
2  * Institut Federatif de Recherche 49
3  * CEA/NeuroSpin, Batiment 145,
4  * 91191 Gif-sur-Yvette cedex
5  * France
6  *
7  * This software is governed by the CeCILL-B license under
8  * French law and abiding by the rules of distribution of free software.
9  * You can use, modify and/or redistribute the software under the
10  * terms of the CeCILL-B license as circulated by CEA, CNRS
11  * and INRIA at the following URL "http://www.cecill.info".
12  *
13  * As a counterpart to the access to the source code and rights to copy,
14  * modify and redistribute granted by the license, users are provided only
15  * with a limited warranty and the software's author, the holder of the
16  * economic rights, and the successive licensors have only limited
17  * liability.
18  *
19  * In this respect, the user's attention is drawn to the risks associated
20  * with loading, using, modifying and/or developing or reproducing the
21  * software by the user in light of its specific status of free software,
22  * that may mean that it is complicated to manipulate, and that also
23  * therefore means that it is reserved for developers and experienced
24  * professionals having in-depth computer knowledge. Users are therefore
25  * encouraged to load and test the software's suitability as regards their
26  * requirements in conditions enabling the security of their systems and/or
27  * data to be ensured and, more generally, to use and operate it in the
28  * same conditions as regards security.
29  *
30  * The fact that you are presently reading this means that you have had
31  * knowledge of the CeCILL-B license and that you accept its terms.
32  */
33 
34 
35 #ifndef CARTOBASE_OBJECT_PROPERTY_H
36 #define CARTOBASE_OBJECT_PROPERTY_H
37 
42 #include <map>
43 #include <stdexcept>
44 
45 
46 namespace carto
47 {
48 
49 
50  //---------------//
51  // PropertySet //
52 //---------------//
53 
75 class PropertySet : virtual public RCObject, public Observable,
76  public DictionaryInterface
77 {
78 public:
81  typedef ::sigc::signal3< void, const Object &, const std::string&,
82  const Object& > Signal;
83 
84  PropertySet();
85  PropertySet( const PropertySet & );
87  virtual ~PropertySet();
88 
89  Signal& getSignalPropertyChanged();
90 
91  // DictionaryInterface methods
92 
93  template <typename T> void addBuiltinProperty( const std::string &, T & );
95  template <typename T> void addBuiltinProperty( const std::string &, T &,
96  bool & provided );
97 
98  template <typename T> bool getProperty( const std::string &, T & ) const;
99  template <typename T> void setProperty( const std::string &, const T & );
100  virtual bool getProperty( const std::string &, Object & ) const;
101  virtual void setProperty( const std::string &, Object );
104  virtual bool removeProperty( const std::string & key )
105  { return _erase( key ); }
106  virtual bool hasProperty( const std::string & ) const;
107  virtual size_t size() const;
108  virtual void clearProperties();
109  virtual void copyBuiltinProperties( const PropertySet & source );
110 
111  // Iterable interface methods
112  virtual Object objectIterator() const;
113 
114  class iterator;
115 
116  inline iterator getIterator() const;
117 
119  template <typename T> void changeBuiltinProperty( const std::string &, T & );
121  template <typename T> void changeBuiltinProperty( const std::string &, T &,
122  bool & provided );
123 
124 private:
125 
126  struct Property
127  {
128  inline Property( const Object &o, bool b )
129  : object( o ), builtin( b ? &PropertySet::_mandatoryProperty : 0 ) {}
130  inline Property( const Object &o, bool *b ) : object( o ), builtin( b ) {}
131  inline Property() : builtin( 0 ) {}
132  Object object;
133  bool *builtin;
134  };
135  typedef std::map< std::string, Property > Properties;
136  typedef std::list< Properties::iterator > PropertiesOrder;
137 
138 public:
139 
141  {
142  public:
143  inline iterator();
144 
145  // DictionaryIteratorInterface methods
146  bool isValid() const;
147  std::string key() const;
148  Object currentValue() const;
149  void next();
150 
151  private:
152 
154 
155  inline iterator( const PropertiesOrder::const_iterator &begin,
156  const PropertiesOrder::const_iterator &end );
157 
158  PropertiesOrder::const_iterator _iterator;
159  PropertiesOrder::const_iterator _end;
160  };
161 
162 
163 private:
164 
165  inline void _insert( const std::string &key, const Property &value );
166  bool _erase( const std::string &key, bool force_builtin = false );
167 
168  Properties _properties;
169  PropertiesOrder _propertiesOrder;
170  Signal _signalPropertyChanged;
171 
172  static bool _mandatoryProperty;
173 };
174 
175 
176 
177  //-------------------------------//
178  // DataTypeCode< PropertySet > //
179 //-------------------------------//
180 
181 #ifndef DOXYGEN_HIDE_INTERNAL_CLASSES
182 
183 template <> class DataTypeCode< PropertySet >
184 {
185 public:
186  std::string objectType() const
187  { return( "PropertySet" ); }
188  std::string dataType() const
189  { return std::string( "Object" ); }
190  static std::string name()
191  {
192  return std::string( "PropertySet" );
193  }
194 };
195 
196 #endif
197 
198 
201 
202 
203  //---------------//
204  // PropertySet //
205 //---------------//
206 
207 
208 //-----------------------------------------------------------------------------
209 template <typename T>
210 void PropertySet::setProperty( const std::string &key, const T &value )
211 {
212  Properties::iterator it = _properties.find( key );
213  if ( it == _properties.end() ) {
214  _insert( key, Property( Object::value( value ), false ) );
215  } else {
216  Object oldValue;
217  bool willemit = false;
218  if( !_signalPropertyChanged.empty() )
219  {
220  willemit = true;
221  if( !it->second.object.isNull() )
222  oldValue = it->second.object->clone();
223  }
224  if ( it->second.builtin ) {
225  it->second.object->setValue( value );
226  if( it->second.builtin != &_mandatoryProperty )
227  *it->second.builtin = true;
228  } else {
229  it->second.object = Object::value( value );
230  }
231  if( willemit )
232  _signalPropertyChanged.sigcemit( Object::reference( *this ),
233  it->first, oldValue );
234  }
235 }
236 
237 
238 //-----------------------------------------------------------------------------
239 template <typename T>
240 void PropertySet::addBuiltinProperty( const std::string &key, T &reference )
241 {
242  Properties::iterator it = _properties.find( key );
243  if ( it == _properties.end() ) {
244  _insert( key, Property( Object::reference( reference ), true ) );
245  } else {
246  throw std::runtime_error( std::string( "Built-in property " ) + key +
247  " already exists" );
248  }
249 }
250 
251 
252 //-----------------------------------------------------------------------------
253 template <typename T>
254 void PropertySet::addBuiltinProperty( const std::string &key, T &reference,
255  bool & provided )
256 {
257  Properties::iterator it = _properties.find( key );
258  if ( it == _properties.end() ) {
259  _insert( key, Property( Object::reference( reference ), &provided ) );
260  } else {
261  throw std::runtime_error( std::string( "Built-in property " ) + key +
262  " already exists" );
263  }
264 }
265 
266 
267 //-----------------------------------------------------------------------------
268 template <typename T>
269 void PropertySet::changeBuiltinProperty( const std::string &key, T &reference )
270 {
271  Properties::iterator it = _properties.find( key );
272  if ( it != _properties.end() ) {
273  _erase( key, true );
274  addBuiltinProperty( key, reference );
275  } else {
276  throw std::runtime_error( std::string( "Built-in property " ) + key +
277  " does not exist" );
278  }
279 }
280 
281 
282 //-----------------------------------------------------------------------------
283 template <typename T>
284 void PropertySet::changeBuiltinProperty( const std::string &key, T &reference,
285  bool & provided )
286 {
287  Properties::iterator it = _properties.find( key );
288  if ( it != _properties.end() ) {
289  _erase( key, true );
290  addBuiltinProperty( key, reference, provided );
291  } else {
292  throw std::runtime_error( std::string( "Built-in property " ) + key +
293  " does not exist" );
294  }
295 }
296 
297 
298 //-----------------------------------------------------------------------------
299 template <typename T>
300 bool PropertySet::getProperty( const std::string &key, T &value ) const
301 {
302  Properties::const_iterator it = _properties.find( key );
303  if ( it != _properties.end() &&
304  ( !it->second.builtin || it->second.builtin == &_mandatoryProperty ) )
305  {
306  return it->second.object->value( value );
307  }
308  return false;
309 }
310 
311 
312 //-----------------------------------------------------------------------------
314 {
315  return iterator( _propertiesOrder.begin(), _propertiesOrder.end() );
316 }
317 
318 
319 //-----------------------------------------------------------------------------
320 inline void PropertySet::_insert( const std::string &key,
321  const Property &value ) {
322  _propertiesOrder.push_back(
323  _properties.insert( std::pair<std::string, Property>( key, value ) ).first
324  );
325 }
326 
327 
328  //-------------------------//
329  // PropertySet::iterator //
330 //-------------------------//
331 
332 //-----------------------------------------------------------------------------
334 {
335 }
336 
337 
338 //-----------------------------------------------------------------------------
340 iterator( const PropertiesOrder::const_iterator &begin,
341  const PropertiesOrder::const_iterator &end ) :
342  _iterator( begin ), _end( end )
343 {
344  while( _iterator != end && (*_iterator)->second.builtin
345  && !*(*_iterator)->second.builtin )
346  ++_iterator;
347 }
348 
349 
350 
351 } // namespace carto
352 
353 
354 #endif
#define DECLARE_GENERIC_OBJECT_TYPE(T)
Definition: object.h:56
virtual bool getProperty(const std::string &key, Object &value) const =0
Access the element ok key key.
Signal & getSignalPropertyChanged()
void addBuiltinProperty(const std::string &, T &)
Definition: property.h:240
virtual size_t size() const
Number of sub-elements.
PropertySet & operator=(const PropertySet &)
This class is just a hint to convert an actual data type to an identifier string used in input/output...
Definition: types.h:110
Base class for reference counted objects (intrusive)
Definition: rcptr.h:106
virtual bool removeProperty(const std::string &key)
remove an element.
Definition: property.h:104
std::string dataType() const
Definition: property.h:188
static Object reference(T &value)
factory function: builds an Object by referencing the value from a ReferenceObject storage wrapper...
Definition: object.h:1532
virtual void clearProperties()
clear the dictionary
virtual ~PropertySet()
::sigc::signal3< void, const Object &, const std::string &, const Object &> Signal
This signal type informs the slots about the sender (this), the property name and its old value...
Definition: property.h:82
virtual Object objectIterator() const
returns an object implementing the IteratorIntrerface
void setProperty(const std::string &, const T &)
Definition: property.h:210
virtual bool hasProperty(const std::string &) const
check if an element exists under the key key
Specialized IteratorInterface for dictionaries.
Definition: object.h:288
A dictionary generic Object.
Definition: property.h:75
virtual void setProperty(const std::string &key, Object value)=0
Set (insert or replace) the element of key key with the value object.
static std::string name()
Definition: property.h:190
static Object value()
factory function: builds an Object by using the default constructor
Definition: object.h:1482
void changeBuiltinProperty(const std::string &, T &)
change the reference to a builtin property
Definition: property.h:269
iterator getIterator() const
Definition: property.h:313
::sigc::trackable Observable
Definition: observable.h:46
bool getProperty(const std::string &, T &) const
Definition: property.h:300
std::string objectType() const
Definition: property.h:186
virtual void copyBuiltinProperties(const PropertySet &source)
Interface for dictionary-like objects.
Definition: object.h:403