Program listing for file kernel/src/utils/SiconosTools/SiconosProperties.hpp

Program listing for file kernel/src/utils/SiconosTools/SiconosProperties.hpp#

  1#ifndef SICONOS_PROPERTIES_HPP
  2#define SICONOS_PROPERTIES_HPP
  3
  4#include "SiconosSerialization.hpp"
  5
  6#include <boost/config.hpp>
  7#include <boost/version.hpp>
  8
  9#if (BOOST_VERSION >= 104000)
 10#include <boost/property_map/property_map.hpp>
 11#else
 12#include <boost/property_map.hpp>
 13#endif
 14
 15
 16#include <SiconosConfig.h>
 17#include <memory>
 18#include <map>
 19
 20
 21#include <boost/mpl/eval_if.hpp>
 22#include <boost/static_assert.hpp>
 23#include <vector>
 24#include <queue>
 25
 26#include <boost/mpl/bool.hpp>
 27#include <boost/type_traits.hpp>
 28
 29namespace Siconos
 30{
 31
 32
 33template <typename T>
 34struct IsSharedPtr : boost::mpl::false_ {};
 35
 36template <typename T>
 37struct IsSharedPtr<std::shared_ptr<T> > : boost::mpl::true_ {};
 38
 39template <typename T>
 40struct IsPointer : boost::mpl::or_<boost::is_pointer<T>, IsSharedPtr<T> > {};
 41
 42
 43template <typename T>
 44struct RemovePointer
 45{
 46  typedef T type;
 47};
 48
 49template <typename T>
 50struct RemovePointer<std::shared_ptr<T> >
 51{
 52  typedef T type;
 53};
 54
 55
 56
 57
 58
 59
 60
 61template<typename G>
 62struct VertexAccess
 63{
 64  typedef VertexAccess type;
 65  typedef typename G::VDescriptor descriptor;
 66  typedef typename G::VIterator iterator;
 67
 68  std::pair<iterator, iterator> elements(G& g)
 69  {
 70    return g.vertices();
 71  }
 72
 73
 74  size_t size(G& g)
 75  {
 76    return g.vertices_number();
 77  }
 78
 79  bool isElem(G& g, typename G::VDescriptor& vd)
 80  {
 81    return g.is_vertex(g.bundle(vd));
 82  }
 83
 84};
 85
 86
 87template<typename G>
 88struct EdgeAccess
 89{
 90  typedef EdgeAccess type;
 91  typedef typename G::EDescriptor descriptor;
 92  typedef typename G::EIterator iterator;
 93
 94  std::pair<iterator, iterator> elements(G& g)
 95  {
 96    return g.edges();
 97  }
 98
 99
100  static size_t size(const G& g)
101  {
102    return g.edges_number();
103  }
104
105  bool isElem(G& g, typename G::EDescriptor& ed)
106  {
107    return g.is_edge(g.source(ed), g.target(ed), g.bundle(ed));
108  }
109};
110
111
112
113template<typename G, typename IndexMap>
114struct VertexOrEdge
115{
116  typedef typename boost::mpl::if_ < boost::is_same<typename G::VIndexAccess, IndexMap>,
117          VertexAccess<G> ,
118          EdgeAccess<G>  >::type Access;
119};
120
121
122template <typename T>
123struct SwapPointedValues
124{
125
126  typedef SwapPointedValues type;
127
128  void operator()(T a, T b)
129  {
130
131    using std::swap;
132    swap(*a, *b);
133  }
134};
135
136
137template <typename T>
138struct SwapValues
139{
140
141  typedef SwapValues type;
142
143  void operator()(T&a, T&b)
144  {
145    using std::swap;
146    swap(a, b);
147  }
148};
149
150template <typename T>
151struct SwapProperties
152{
153  typedef typename boost::mpl::if_ < IsPointer<T>,
154          SwapPointedValues<T>,
155          SwapValues<T> >::type type;
156};
157
158template <typename T>
159struct GetPointedValue
160{
161  typedef GetPointedValue type;
162
163  typename RemovePointer<T>::type& operator()(T a)
164  {
165    return *a;
166  }
167};
168
169template <typename T>
170struct GetValue
171{
172  typedef GetValue type;
173
174  T& operator()(T& a)
175  {
176    return a;
177  }
178};
179
180template <typename T>
181struct GetProperty
182{
183
184  typedef typename boost::mpl::if_ < IsPointer<T>,
185          GetPointedValue<T>,
186          GetValue<T> >::type type;
187
188};
189
190
191
192template<typename T, typename G, typename IndexMap>
193
194
195class Properties
196{
197
198public:
199  typedef typename VertexOrEdge<G, IndexMap>::Access Access;
200
201  Access access;
202
203  typedef typename boost::property_traits<IndexMap>::key_type  key_type;
204  typedef T value_type;
205  typedef typename std::iterator_traits <
206  typename std::vector<T>::iterator >::reference reference;
207  typedef boost::lvalue_property_map_tag category;
208
209
210public:
211  G& _g;
212
213
214  std::shared_ptr< std::map<key_type, T> > _store;
215
216  int _stamp;
217
218
219
220
221  Properties(G& g) : _g(g), _store(new std::map<key_type, T>()), _stamp(-1)
222  {}
223
224
225
226  void insert(const key_type& v, T t)
227  {
228    (*_store)[v] = t;
229  };
230
231
232  reference operator[](const key_type& v)
233  {
234    return (*_store)[v];
235  };
236
237
238  value_type at(const key_type& v)
239  {
240    return _store->at(v);
241  };
242
243
244  reference find(const key_type& v)
245  {
246    return _store->find(v).second;
247  };
248
249
250  inline bool hasKey(const key_type& v)
251  {
252    return _store->find(v) != _store->end();
253  };
254
255
256  typedef void serializable;
257
258
259};
260
261
262
263template<typename T, typename G>
264class VertexProperties : public Properties<T, G, typename G::VIndexAccess>
265{
266public:
267  VertexProperties(G& g) : Properties<T, G, typename G::VIndexAccess>(g)
268  {};
269
270
271  typedef void serializable;
272
273
274};
275
276
277template<typename T, typename G>
278class VertexSPProperties : public VertexProperties<std::shared_ptr<T>, G>
279{
280public:
281  VertexSPProperties(G& g) : VertexProperties<std::shared_ptr<T>, G>(g)
282  {};
283
284
285  typedef typename boost::property_traits<typename G::VIndexAccess>::key_type  key_type;
286  typedef void serializable;
287
288
289  inline T& getRef(const key_type& v)
290  {
291    return *((*this->_store)[v]).get();
292  };
293};
294
295
296
297template<typename T, typename G>
298class EdgeProperties : public Properties<T, G, typename G::EIndexAccess>
299{
300public:
301  EdgeProperties(G& g) : Properties<T, G, typename G::EIndexAccess>(g)
302  {};
303
304
305  typedef void serializable;
306
307
308};
309
310
311template<typename T, typename G>
312VertexProperties<T, G> vertexProperties(G& g)
313{
314  return VertexProperties<T, G>(g);
315}
316
317
318template<typename T, typename G>
319EdgeProperties<T, G> edgeProperties(G& g)
320{
321  return EdgeProperties<T, G>(g);
322}
323
324
325
326
327template<typename T, typename G, typename IndexMap>
328class SubProperties
329{
330private:
331  typedef Properties<T, G, IndexMap> RefProperties;
332  RefProperties _properties;
333  G& _g;
334
335  typedef typename boost::property_traits<IndexMap>::key_type  key_type;
336  typedef T value_type;
337  typedef typename std::iterator_traits <
338  typename std::vector<T>::iterator >::reference reference;
339  typedef boost::lvalue_property_map_tag category;
340
341public:
342
343  SubProperties(RefProperties& p, G& g)
344    : _properties(p), _g(g) {}
345
346  reference operator[](const key_type& v)
347  {
348    return _properties[_g.descriptor0(v)];
349  }
350
351};
352
353template<typename T, typename G>
354class VertexSubProperties : public SubProperties<T, G, typename G::VIndexAccess>
355{
356public:
357  typedef Properties<T, G, typename G::VIndexAccess> RefProperties;
358
359  VertexSubProperties(RefProperties& p, G& g) : SubProperties<T, G, typename G::VIndexAccess>(p, g)
360  {};
361};
362
363template<typename T, typename G>
364class EdgeSubProperties : public SubProperties<T, G, typename G::EIndexAccess>
365{
366public:
367  typedef Properties<T, G, typename G::EIndexAccess> RefProperties;
368
369  EdgeSubProperties(RefProperties& p, G& g) : SubProperties<T, G, typename G::EIndexAccess>(p, g)
370  {};
371};
372
373
374}
375
376
377
378#include <boost/preprocessor/seq/seq.hpp>
379#include <boost/preprocessor/seq/for_each.hpp>
380#include <boost/preprocessor/tuple/elem.hpp>
381#include <boost/preprocessor/cat.hpp>
382
383#define I_DECLARE_MEMBERS(r,gt,p) \
384  Siconos:: BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(3,0,p),Properties)< BOOST_PP_TUPLE_ELEM(3,1,p), BOOST_PP_CAT(_,gt)> BOOST_PP_TUPLE_ELEM(3,2,p);
385
386#define I_CONS_MEMBERS(r,gt,p) \
387  BOOST_PP_TUPLE_ELEM(3,2,p) (Siconos:: BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(3,0,p),Properties)< BOOST_PP_TUPLE_ELEM(3,1,p), BOOST_PP_CAT(_,gt)>(*static_cast<BOOST_PP_CAT(_,gt)*>(this))),
388
389#define INSTALL_GRAPH_PROPERTIES(GraphType, PROPERTIES)                 \
390  BOOST_PP_SEQ_FOR_EACH(I_DECLARE_MEMBERS, BOOST_PP_CAT(GraphType, Graph), PROPERTIES) \
391  bool dummy;                                                           \
392                                                                        \
393  BOOST_PP_CAT(GraphType, Graph)() :                                    \
394    BOOST_PP_SEQ_FOR_EACH(I_CONS_MEMBERS, BOOST_PP_CAT(GraphType, Graph), PROPERTIES) dummy(true) {} \
395
396#endif