dune-geometry
2.2.0
|
00001 #ifndef DUNE_GEOMETRY_TOPOLOGYFACTORY_HH 00002 #define DUNE_GEOMETRY_TOPOLOGYFACTORY_HH 00003 00004 #include <vector> 00005 #include <map> 00006 00007 #include <dune/common/fvector.hh> 00008 #include <dune/geometry/genericgeometry/conversion.hh> 00009 #include <dune/geometry/genericgeometry/topologytypes.hh> 00010 00011 namespace Dune 00012 { 00013 00032 template <class Traits> 00033 struct TopologyFactory 00034 { 00035 // extract types from Traits class 00036 static const unsigned int dimension = Traits::dimension; 00037 typedef typename Traits::Key Key; 00038 typedef typename Traits::Object Object; 00039 typedef typename Traits::Factory Factory; 00045 static Object *create(unsigned int topologyId, const Key &key) DUNE_DEPRECATED_MSG("use create(Dune::GeometryType, Key) instead") 00046 { 00047 Object *object; 00048 GenericGeometry::IfTopology< Maker, dimension >::apply( topologyId, key, object ); 00049 return object; 00050 } 00052 static Object *create(const Dune::GeometryType >, const Key &key) 00053 { 00054 Object *object; 00055 GenericGeometry::IfTopology< Maker, dimension >::apply( gt.id(), key, object ); 00056 return object; 00057 } 00059 template <class Topology> 00060 static Object *create(const Key &key) 00061 { 00062 return Factory::template createObject<Topology> ( key ); 00063 } 00065 static void release( Object *object) 00066 { 00067 delete object; 00068 } 00069 private: 00070 // Internal maker class used in ifTopology helper 00071 template< class Topology > 00072 struct Maker 00073 { 00074 static void apply ( const Key &key, Object *&object ) 00075 { 00076 object = create<Topology>( key ); 00077 }; 00078 }; 00079 }; 00080 00081 00086 template <class Factory> 00087 struct TopologySingletonFactory 00088 { 00089 static const unsigned int dimension = Factory::dimension; 00090 typedef typename Factory::Key Key; 00091 typedef const typename Factory::Object Object; 00093 static Object *create ( const unsigned int topologyId, const Key &key ) DUNE_DEPRECATED 00094 { 00095 assert( topologyId < numTopologies ); 00096 return create( Dune::GeometryType( topologyId, dimension ), key ); 00097 } 00099 static Object *create ( const Dune::GeometryType >, const Key &key ) 00100 { 00101 assert( gt.id() < numTopologies ); 00102 return instance().getObject( gt, key ); 00103 } 00105 template< class Topology > 00106 static Object *create ( const Key &key ) 00107 { 00108 dune_static_assert( (Topology::dimension == dimension), 00109 "Topology with incompatible dimension used" ); 00110 return instance().template getObject< Topology >( key ); 00111 } 00113 static void release ( Object *object ) 00114 {} 00115 private: 00116 static TopologySingletonFactory &instance () 00117 { 00118 static TopologySingletonFactory instance; 00119 return instance; 00120 } 00121 00122 static const unsigned int numTopologies = (1 << dimension); 00123 typedef FieldVector< Object *, numTopologies > Array; 00124 typedef std::map< Key, Array > Storage; 00125 00126 TopologySingletonFactory () 00127 {} 00128 ~TopologySingletonFactory () 00129 { 00130 const typename Storage::iterator end = storage_.end(); 00131 for( typename Storage::iterator it = storage_.begin(); it != end; ++it ) 00132 { 00133 for( unsigned int topologyId = 0; topologyId < numTopologies; ++topologyId ) 00134 { 00135 Object *&object = it->second[ topologyId ]; 00136 if( object != 0 ) 00137 Factory::release( object ); 00138 object = 0; 00139 } 00140 } 00141 } 00142 00143 Object *&find( const unsigned int topologyId, const Key &key ) 00144 { 00145 typename Storage::iterator it = storage_.find( key ); 00146 if( it == storage_.end() ) 00147 it = storage_.insert( std::make_pair( key, Array( 0 ) ) ).first; 00148 return it->second[ topologyId ]; 00149 } 00150 00151 Object *getObject ( const Dune::GeometryType >, const Key &key ) 00152 { 00153 Object *&object = find( gt.id(), key ); 00154 if( object == 0 ) 00155 object = Factory::create( gt, key ); 00156 return object; 00157 } 00158 00159 template< class Topology > 00160 Object *getObject ( const Key &key ) 00161 { 00162 Object *&object = find(Topology::id,key); 00163 if( object == 0 ) 00164 object = Factory::template create< Topology >( key ); 00165 return object; 00166 } 00167 Storage storage_; 00168 }; 00169 00170 } 00171 00172 #endif // #ifndef DUNE_GEOMETRY_TOPOLOGYFACTORY_HH