cartobase  5.1.2
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 
87  virtual ~PropertySet();
88 
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 
99  template <typename T> bool getProperty( const std::string &, T & ) const;
100  template <typename T> void setProperty( const std::string &, const T & );
101  virtual bool getProperty( const std::string &, Object & ) const;
102  virtual void setProperty( const std::string &, Object );
103  virtual bool removeProperty( const std::string & key )
104  { return _erase( key ); }
105  virtual bool hasProperty( const std::string & ) const;
106  virtual size_t size() const;
107  virtual void clearProperties();
108  virtual void copyBuiltinProperties( const PropertySet & source );
109 
110  // Iterable interface methods
111  virtual Object objectIterator() const;
112 
113  class iterator;
114 
115  inline iterator getIterator() const;
116 
118  template <typename T> void changeBuiltinProperty( const std::string &, T & );
120  template <typename T> void changeBuiltinProperty( const std::string &, T &,
121  bool & provided );
122 
123 private:
124 
125  struct Property
126  {
127  inline Property( const Object &o, bool b )
128  : object( o ), builtin( b ? &PropertySet::_mandatoryProperty : 0 ) {}
129  inline Property( const Object &o, bool *b ) : object( o ), builtin( b ) {}
130  inline Property() : builtin( 0 ) {}
131  Object object;
132  bool *builtin;
133  };
134  typedef std::map< std::string, Property > Properties;
135  typedef std::list< Properties::iterator > PropertiesOrder;
136 
137 public:
138 
140  {
141  public:
142  inline iterator();
143 
144  // DictionaryIteratorInterface methods
145  bool isValid() const;
146  std::string key() const;
147  Object keyObject() 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 
199 DECLARE_GENERIC_OBJECT_TYPE( PropertySet )
200 DECLARE_GENERIC_OBJECT_TYPE( PropertySet::iterator )
201 
202 
203  //---------------//
204  // PropertySet //
205 //---------------//
206 
207 
208 //-----------------------------------------------------------------------------
209 template <typename T>
210 inline
211 void PropertySet::setProperty( const std::string &key, const T &value )
212 {
213  Properties::iterator it = _properties.find( key );
214  if ( it == _properties.end() ) {
215  _insert( key, Property( Object::value( value ), false ) );
216  } else {
217  Object oldValue;
218  bool willemit = false;
219  if( !_signalPropertyChanged.empty() )
220  {
221  willemit = true;
222  if( !it->second.object.isNull() )
223  oldValue = it->second.object->clone();
224  }
225  if ( it->second.builtin ) {
226  it->second.object->setValue( value );
227  if( it->second.builtin != &_mandatoryProperty )
228  *it->second.builtin = true;
229  } else {
230  it->second.object = Object::value( value );
231  }
232  if( willemit )
233  _signalPropertyChanged.sigcemit( Object::reference( *this ),
234  it->first, oldValue );
235  }
236 }
237 
238 
239 //-----------------------------------------------------------------------------
240 template <typename T>
241 inline
242 void PropertySet::addBuiltinProperty( const std::string &key, T &reference )
243 {
244  Properties::iterator it = _properties.find( key );
245  if ( it == _properties.end() ) {
246  _insert( key, Property( Object::reference( reference ), true ) );
247  } else {
248  throw std::runtime_error( std::string( "Built-in property " ) + key +
249  " already exists" );
250  }
251 }
252 
253 
254 //-----------------------------------------------------------------------------
255 template <typename T>
256 inline
257 void PropertySet::addBuiltinProperty( const std::string &key, T &reference,
258  bool & provided )
259 {
260  Properties::iterator it = _properties.find( key );
261  if ( it == _properties.end() ) {
262  _insert( key, Property( Object::reference( reference ), &provided ) );
263  } else {
264  throw std::runtime_error( std::string( "Built-in property " ) + key +
265  " already exists" );
266  }
267 }
268 
269 
270 //-----------------------------------------------------------------------------
271 template <typename T>
272 inline
273 void PropertySet::changeBuiltinProperty( const std::string &key, T &reference )
274 {
275  Properties::iterator it = _properties.find( key );
276  if ( it != _properties.end() ) {
277  _erase( key, true );
278  addBuiltinProperty( key, reference );
279  } else {
280  throw std::runtime_error( std::string( "Built-in property " ) + key +
281  " does not exist" );
282  }
283 }
284 
285 
286 //-----------------------------------------------------------------------------
287 template <typename T>
288 inline
289 void PropertySet::changeBuiltinProperty( const std::string &key, T &reference,
290  bool & provided )
291 {
292  Properties::iterator it = _properties.find( key );
293  if ( it != _properties.end() ) {
294  _erase( key, true );
295  addBuiltinProperty( key, reference, provided );
296  } else {
297  throw std::runtime_error( std::string( "Built-in property " ) + key +
298  " does not exist" );
299  }
300 }
301 
302 
303 //-----------------------------------------------------------------------------
304 template <typename T>
305 inline
306 bool PropertySet::getProperty( const std::string &key, T &value ) const
307 {
308  Properties::const_iterator it = _properties.find( key );
309  if ( it != _properties.end() &&
310  ( !it->second.builtin || it->second.builtin == &_mandatoryProperty ) )
311  {
312  return it->second.object->value( value );
313  }
314  return false;
315 }
316 
317 
318 //-----------------------------------------------------------------------------
320 {
321  return iterator( _propertiesOrder.begin(), _propertiesOrder.end() );
322 }
323 
324 
325 //-----------------------------------------------------------------------------
326 inline void PropertySet::_insert( const std::string &key,
327  const Property &value ) {
328  _propertiesOrder.push_back(
329  _properties.insert( std::pair<std::string, Property>( key, value ) ).first
330  );
331 }
332 
333 
334  //-------------------------//
335  // PropertySet::iterator //
336 //-------------------------//
337 
338 //-----------------------------------------------------------------------------
340 {
341 }
342 
343 
344 //-----------------------------------------------------------------------------
346 iterator( const PropertiesOrder::const_iterator &begin,
347  const PropertiesOrder::const_iterator &end ) :
348  _iterator( begin ), _end( end )
349 {
350  while( _iterator != end && (*_iterator)->second.builtin
351  && !*(*_iterator)->second.builtin )
352  ++_iterator;
353 }
354 
355 
356 
357 } // namespace carto
358 
359 
360 #endif
std::string objectType() const
Definition: property.h:186
static std::string name()
Definition: property.h:190
std::string dataType() const
Definition: property.h:188
This class is just a hint to convert an actual data type to an identifier string used in input/output...
Definition: types.h:111
Interface for dictionary-like objects.
Definition: object.h:414
virtual bool getProperty(const std::string &key, Object &value) const =0
Access the element ok key key.
Specialized IteratorInterface for dictionaries.
Definition: object.h:289
Specialized IteratorInterface for key/value storage.
Definition: object.h:265
static Object reference(T &value)
factory function: builds an Object by referencing the value from a ReferenceObject storage wrapper.
Definition: object.h:1546
static Object value()
factory function: builds an Object by using the default constructor
Definition: object.h:1496
void next()
Point to the next element of the iterable container.
Object keyObject() const
Access the key of the current element.
std::string key() const
Access the key of the current dictionary element.
bool isValid() const
true if the iterator points to a valid value, false when the end of the iterable container has been r...
Object currentValue() const
Access the value of the element pointed to by the iterator.
A dictionary generic Object.
Definition: property.h:77
Signal & getSignalPropertyChanged()
::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 void clearProperties()
clear the dictionary
void setProperty(const std::string &, const T &)
Definition: property.h:211
virtual bool removeProperty(const std::string &key)
remove an element.
Definition: property.h:103
virtual bool hasProperty(const std::string &) const
check if an element exists under the key key
void addBuiltinProperty(const std::string &, T &)
Definition: property.h:242
PropertySet & operator=(const PropertySet &)
virtual ~PropertySet()
PropertySet(const PropertySet &)
virtual void setProperty(const std::string &, Object)
Set (insert or replace) the element of key key with the value object.
virtual size_t size() const
Number of sub-elements.
virtual void copyBuiltinProperties(const PropertySet &source)
void changeBuiltinProperty(const std::string &, T &)
change the reference to a builtin property
Definition: property.h:273
virtual Object objectIterator() const
returns an object implementing the IteratorIntrerface
virtual bool getProperty(const std::string &key, Object &value) const=0
Access the element ok key key.
iterator getIterator() const
Definition: property.h:319
virtual bool getProperty(const std::string &, Object &) const
Access the element ok key key.
Base class for reference counted objects (intrusive)
Definition: rcptr.h:110
::sigc::trackable Observable
Definition: observable.h:46
#define DECLARE_GENERIC_OBJECT_TYPE(T)
Definition: object.h:56