dune-grid
2.1.1
|
00001 #ifndef DUNE_TOPOLOGYFACTORY_HH 00002 #define DUNE_TOPOLOGYFACTORY_HH 00003 00004 #include <vector> 00005 #include <map> 00006 00007 #include <dune/common/fvector.hh> 00008 #include <dune/grid/genericgeometry/conversion.hh> 00009 #include <dune/grid/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; 00041 static Object *create(unsigned int topologyId, const Key &key) DUNE_DEPRECATED 00042 { 00043 Object *object; 00044 GenericGeometry::IfTopology< Maker, dimension >::apply( topologyId, key, object ); 00045 return object; 00046 } 00048 static Object *create(const Dune::GeometryType >, const Key &key) 00049 { 00050 Object *object; 00051 GenericGeometry::IfTopology< Maker, dimension >::apply( gt.id(), key, object ); 00052 return object; 00053 } 00055 template <class Topology> 00056 static Object *create(const Key &key) 00057 { 00058 return Factory::template createObject<Topology> ( key ); 00059 } 00061 static void release( Object *object) 00062 { 00063 delete object; 00064 } 00065 private: 00066 // Internal maker class used in ifTopology helper 00067 template< class Topology > 00068 struct Maker 00069 { 00070 static void apply ( const Key &key, Object *&object ) 00071 { 00072 object = create<Topology>( key ); 00073 }; 00074 }; 00075 }; 00076 00077 00082 template <class Factory> 00083 struct TopologySingletonFactory 00084 { 00085 static const unsigned int dimension = Factory::dimension; 00086 typedef typename Factory::Key Key; 00087 typedef const typename Factory::Object Object; 00089 static Object *create ( const unsigned int topologyId, const Key &key ) DUNE_DEPRECATED 00090 { 00091 assert( topologyId < numTopologies ); 00092 return create( Dune::GeometryType( topologyId, dimension ), key ); 00093 } 00095 static Object *create ( const Dune::GeometryType >, const Key &key ) 00096 { 00097 assert( gt.id() < numTopologies ); 00098 return instance().getObject( gt, key ); 00099 } 00101 template< class Topology > 00102 static Object *create ( const Key &key ) 00103 { 00104 dune_static_assert( (Topology::dimension == dimension), 00105 "Topology with incompatible dimension used" ); 00106 return instance().template getObject< Topology >( key ); 00107 } 00109 static void release ( Object *object ) 00110 {} 00111 private: 00112 static TopologySingletonFactory &instance () 00113 { 00114 static TopologySingletonFactory instance; 00115 return instance; 00116 } 00117 00118 static const unsigned int numTopologies = (1 << dimension); 00119 typedef FieldVector< Object *, numTopologies > Array; 00120 typedef std::map< Key, Array > Storage; 00121 00122 TopologySingletonFactory () 00123 {} 00124 ~TopologySingletonFactory () 00125 { 00126 const typename Storage::iterator end = storage_.end(); 00127 for( typename Storage::iterator it = storage_.begin(); it != end; ++it ) 00128 { 00129 for( unsigned int topologyId = 0; topologyId < numTopologies; ++topologyId ) 00130 { 00131 Object *&object = it->second[ topologyId ]; 00132 if( object != 0 ) 00133 Factory::release( object ); 00134 object = 0; 00135 } 00136 } 00137 } 00138 00139 Object *&find( const unsigned int topologyId, const Key &key ) 00140 { 00141 typename Storage::iterator it = storage_.find( key ); 00142 if( it == storage_.end() ) 00143 it = storage_.insert( std::make_pair( key, Array( 0 ) ) ).first; 00144 return it->second[ topologyId ]; 00145 } 00146 00147 Object *getObject ( const Dune::GeometryType >, const Key &key ) 00148 { 00149 Object *&object = find( gt.id(), key ); 00150 if( object == 0 ) 00151 object = Factory::create( gt, key ); 00152 return object; 00153 } 00154 00155 template< class Topology > 00156 Object *getObject ( const Key &key ) 00157 { 00158 Object *&object = find(Topology::id,key); 00159 if( object == 0 ) 00160 object = Factory::template create< Topology >( key ); 00161 return object; 00162 } 00163 Storage storage_; 00164 }; 00165 00166 } 00167 00168 #endif // #ifndef DUNE_TOPOLOGYFACTORY_HH