dune-geometry  2.2.0
topologyfactory.hh
Go to the documentation of this file.
1 #ifndef DUNE_GEOMETRY_TOPOLOGYFACTORY_HH
2 #define DUNE_GEOMETRY_TOPOLOGYFACTORY_HH
3 
4 #include <vector>
5 #include <map>
6 
7 #include <dune/common/fvector.hh>
10 
11 namespace Dune
12 {
13 
32  template <class Traits>
34  {
35  // extract types from Traits class
36  static const unsigned int dimension = Traits::dimension;
37  typedef typename Traits::Key Key;
38  typedef typename Traits::Object Object;
39  typedef typename Traits::Factory Factory;
45  static Object *create(unsigned int topologyId, const Key &key) DUNE_DEPRECATED_MSG("use create(Dune::GeometryType, Key) instead")
46  {
47  Object *object;
49  return object;
50  }
52  static Object *create(const Dune::GeometryType &gt, const Key &key)
53  {
54  Object *object;
56  return object;
57  }
59  template <class Topology>
60  static Object *create(const Key &key)
61  {
62  return Factory::template createObject<Topology> ( key );
63  }
65  static void release( Object *object)
66  {
67  delete object;
68  }
69  private:
70  // Internal maker class used in ifTopology helper
71  template< class Topology >
72  struct Maker
73  {
74  static void apply ( const Key &key, Object *&object )
75  {
76  object = create<Topology>( key );
77  };
78  };
79  };
80 
81 
86  template <class Factory>
88  {
89  static const unsigned int dimension = Factory::dimension;
90  typedef typename Factory::Key Key;
91  typedef const typename Factory::Object Object;
93  static Object *create ( const unsigned int topologyId, const Key &key ) DUNE_DEPRECATED
94  {
95  assert( topologyId < numTopologies );
96  return create( Dune::GeometryType( topologyId, dimension ), key );
97  }
99  static Object *create ( const Dune::GeometryType &gt, const Key &key )
100  {
101  assert( gt.id() < numTopologies );
102  return instance().getObject( gt, key );
103  }
105  template< class Topology >
106  static Object *create ( const Key &key )
107  {
108  dune_static_assert( (Topology::dimension == dimension),
109  "Topology with incompatible dimension used" );
110  return instance().template getObject< Topology >( key );
111  }
113  static void release ( Object *object )
114  {}
115  private:
116  static TopologySingletonFactory &instance ()
117  {
118  static TopologySingletonFactory instance;
119  return instance;
120  }
121 
122  static const unsigned int numTopologies = (1 << dimension);
123  typedef FieldVector< Object *, numTopologies > Array;
124  typedef std::map< Key, Array > Storage;
125 
126  TopologySingletonFactory ()
127  {}
128  ~TopologySingletonFactory ()
129  {
130  const typename Storage::iterator end = storage_.end();
131  for( typename Storage::iterator it = storage_.begin(); it != end; ++it )
132  {
133  for( unsigned int topologyId = 0; topologyId < numTopologies; ++topologyId )
134  {
135  Object *&object = it->second[ topologyId ];
136  if( object != 0 )
137  Factory::release( object );
138  object = 0;
139  }
140  }
141  }
142 
143  Object *&find( const unsigned int topologyId, const Key &key )
144  {
145  typename Storage::iterator it = storage_.find( key );
146  if( it == storage_.end() )
147  it = storage_.insert( std::make_pair( key, Array( 0 ) ) ).first;
148  return it->second[ topologyId ];
149  }
150 
151  Object *getObject ( const Dune::GeometryType &gt, const Key &key )
152  {
153  Object *&object = find( gt.id(), key );
154  if( object == 0 )
155  object = Factory::create( gt, key );
156  return object;
157  }
158 
159  template< class Topology >
160  Object *getObject ( const Key &key )
161  {
162  Object *&object = find(Topology::id,key);
163  if( object == 0 )
164  object = Factory::template create< Topology >( key );
165  return object;
166  }
167  Storage storage_;
168  };
169 
170 }
171 
172 #endif // #ifndef DUNE_GEOMETRY_TOPOLOGYFACTORY_HH