cartobase  4.5.0
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 
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 & );
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 
117 private:
118 
119  struct Property
120  {
121  inline Property( const Object &o, bool b )
122  : object( o ), builtin( b ? &PropertySet::_mandatoryProperty : 0 ) {}
123  inline Property( const Object &o, bool *b ) : object( o ), builtin( b ) {}
124  inline Property() : builtin( 0 ) {}
125  Object object;
126  bool *builtin;
127  };
128  typedef std::map< std::string, Property > Properties;
129  typedef std::list< Properties::iterator > PropertiesOrder;
130 
131 public:
132 
134  {
135  public:
136  inline iterator();
137 
138  // DictionaryIteratorInterface methods
139  bool isValid() const;
140  std::string key() const;
141  Object currentValue() const;
142  void next();
143 
144  private:
145 
147 
148  inline iterator( const PropertiesOrder::const_iterator &begin,
149  const PropertiesOrder::const_iterator &end );
150 
151  PropertiesOrder::const_iterator _iterator;
152  PropertiesOrder::const_iterator _end;
153  };
154 
155 
156 private:
157 
158  inline void _insert( const std::string &key, const Property &value );
159 
160  Properties _properties;
161  PropertiesOrder _propertiesOrder;
162  Signal _signalPropertyChanged;
163 
164  static bool _mandatoryProperty;
165 };
166 
167 
168 
169  //-------------------------------//
170  // DataTypeCode< PropertySet > //
171 //-------------------------------//
172 
173 #ifndef DOXYGEN_HIDE_INTERNAL_CLASSES
174 
175 template <> class DataTypeCode< PropertySet >
176 {
177 public:
178  std::string objectType() const
179  { return( "PropertySet" ); }
180  std::string dataType() const
181  { return std::string( "Object" ); }
182  static std::string name()
183  {
184  return std::string( "PropertySet" );
185  }
186 };
187 
188 #endif
189 
190 
191 DECLARE_GENERIC_OBJECT_TYPE( PropertySet )
192 DECLARE_GENERIC_OBJECT_TYPE( PropertySet::iterator )
193 
194 
195  //---------------//
196  // PropertySet //
197 //---------------//
198 
199 
200 //-----------------------------------------------------------------------------
201 template <typename T>
202 void PropertySet::setProperty( const std::string &key, const T &value )
203 {
204  Properties::iterator it = _properties.find( key );
205  if ( it == _properties.end() ) {
206  _insert( key, Property( Object::value( value ), false ) );
207  } else {
208  Object oldValue;
209  bool willemit = false;
210  if( !_signalPropertyChanged.empty() )
211  {
212  willemit = true;
213  if( !it->second.object.isNull() )
214  oldValue = it->second.object->clone();
215  }
216  if ( it->second.builtin ) {
217  it->second.object->setValue( value );
218  if( it->second.builtin != &_mandatoryProperty )
219  *it->second.builtin = true;
220  } else {
221  it->second.object = Object::value( value );
222  }
223  if( willemit )
224  _signalPropertyChanged.sigcemit( Object::reference( *this ),
225  it->first, oldValue );
226  }
227 }
228 
229 
230 //-----------------------------------------------------------------------------
231 template <typename T>
232 void PropertySet::addBuiltinProperty( const std::string &key, T &reference )
233 {
234  Properties::iterator it = _properties.find( key );
235  if ( it == _properties.end() ) {
236  _insert( key, Property( Object::reference( reference ), true ) );
237  } else {
238  throw std::runtime_error( std::string( "Built-in property " ) + key +
239  " already exists" );
240  }
241 }
242 
243 
244 //-----------------------------------------------------------------------------
245 template <typename T>
246 void PropertySet::addBuiltinProperty( const std::string &key, T &reference,
247  bool & provided )
248 {
249  Properties::iterator it = _properties.find( key );
250  if ( it == _properties.end() ) {
251  _insert( key, Property( Object::reference( reference ), &provided ) );
252  } else {
253  throw std::runtime_error( std::string( "Built-in property " ) + key +
254  " already exists" );
255  }
256 }
257 
258 
259 //-----------------------------------------------------------------------------
260 template <typename T>
261 bool PropertySet::getProperty( const std::string &key, T &value ) const
262 {
263  Properties::const_iterator it = _properties.find( key );
264  if ( it != _properties.end() &&
265  ( !it->second.builtin || it->second.builtin == &_mandatoryProperty ) )
266  {
267  return it->second.object->value( value );
268  }
269  return false;
270 }
271 
272 
273 //-----------------------------------------------------------------------------
275 {
276  return iterator( _propertiesOrder.begin(), _propertiesOrder.end() );
277 }
278 
279 
280 //-----------------------------------------------------------------------------
281 inline void PropertySet::_insert( const std::string &key,
282  const Property &value ) {
283  _propertiesOrder.push_back(
284  _properties.insert( std::pair<std::string, Property>( key, value ) ).first
285  );
286 }
287 
288 
289  //-------------------------//
290  // PropertySet::iterator //
291 //-------------------------//
292 
293 //-----------------------------------------------------------------------------
295 {
296 }
297 
298 
299 //-----------------------------------------------------------------------------
301 iterator( const PropertiesOrder::const_iterator &begin,
302  const PropertiesOrder::const_iterator &end ) :
303  _iterator( begin ), _end( end )
304 {
305  while( _iterator != end && (*_iterator)->second.builtin
306  && !*(*_iterator)->second.builtin )
307  ++_iterator;
308 }
309 
310 
311 
312 } // namespace carto
313 
314 
315 #endif
std::string dataType() const
Definition: property.h:180
#define DECLARE_GENERIC_OBJECT_TYPE(T)
Definition: object.h:55
iterator getIterator() const
Definition: property.h:274
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:232
virtual bool removeProperty(const std::string &)
remove an element.
virtual Object objectIterator() const
returns an object implementing the IteratorIntrerface
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
Object currentValue() const
Access the value of the element pointed to by the iterator.
Base class for reference counted objects (intrusive)
Definition: rcptr.h:105
static Object reference(T &value)
factory function: builds an Object by referencing the value from a ReferenceObject storage wrapper...
Definition: object.h:1470
virtual void clearProperties()
clear the dictionary
virtual ~PropertySet()
virtual size_t size() const
Number of sub-elements.
std::string objectType() const
Definition: property.h:178
::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
void setProperty(const std::string &, const T &)
Definition: property.h:202
Specialized IteratorInterface for dictionaries.
Definition: object.h:263
A dictionary generic Object.
Definition: property.h:75
bool isValid() const
true if the iterator points to a valid value, false when the end of the iterable container has been r...
virtual void setProperty(const std::string &key, Object value)=0
Set (insert or replace) the element of key key with the value object.
bool getProperty(const std::string &, T &) const
Definition: property.h:261
void next()
Point to the next element of the iterable container.
static std::string name()
Definition: property.h:182
static Object value()
factory function: builds an Object by using the default constructor
Definition: object.h:1420
::sigc::trackable Observable
Definition: observable.h:46
std::string key() const
Access the key of the current dictionary element.
virtual void copyBuiltinProperties(const PropertySet &source)
virtual bool hasProperty(const std::string &) const
check if an element exists under the key key
Interface for dictionary-like objects.
Definition: object.h:354