DUNE PDELab (2.8)

persistentcontainermap.hh
1// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2// vi: set et ts=4 sw=2 sts=2:
3#ifndef DUNE_PERSISTENTCONTAINERMAP_HH
4#define DUNE_PERSISTENTCONTAINERMAP_HH
5
6#include <algorithm>
7#include <cassert>
8#include <type_traits>
9#include <utility>
10
11#include <dune/common/hybridutilities.hh>
14
15namespace Dune
16{
17
18 // PersistentContainerMap
19 // ----------------------
20
22 template< class G, class IdSet, class Map >
24 {
26
27 protected:
28 template< class reference, class iterator >
29 class IteratorWrapper;
30
31 public:
32 typedef G Grid;
33
34 typedef typename Map::mapped_type Value;
35 typedef typename Map::size_type Size;
36
37 typedef IteratorWrapper< const Value, typename Map::const_iterator > ConstIterator;
38 typedef IteratorWrapper< Value, typename Map::iterator > Iterator;
39
40 PersistentContainerMap ( const Grid &grid, int codim, const IdSet &idSet, const Value &value )
41 : grid_( &grid ),
42 codim_( codim ),
43 idSet_( &idSet ),
44 data_()
45 {
46 resize( value );
47 }
48
49 template< class Entity >
50 const Value &operator[] ( const Entity &entity ) const
51 {
52 assert( Entity::codimension == codimension() );
53 typename Map::const_iterator pos = data_.find( idSet().id( entity ) );
54 assert( pos != data_.end() );
55 return pos->second;
56 }
57
58 template< class Entity >
59 Value &operator[] ( const Entity &entity )
60 {
61 assert( Entity::codimension == codimension() );
62 typename Map::iterator pos = data_.find( idSet().id( entity ) );
63 assert( pos != data_.end() );
64 return pos->second;
65 }
66
67 template< class Entity >
68 const Value &operator() ( const Entity &entity, int subEntity ) const
69 {
70 typename Map::const_iterator pos = data_.find( idSet().subId( entity, subEntity, codimension() ) );
71 assert( pos != data_.end() );
72 return pos->second;
73 }
74
75 template< class Entity >
76 Value &operator() ( const Entity &entity, int subEntity )
77 {
78 typename Map::iterator pos = data_.find( idSet().subId( entity, subEntity, codimension() ) );
79 assert( pos != data_.end() );
80 return pos->second;
81 }
82
83 Size size () const { return data_.size(); }
84
85 void resize ( const Value &value = Value() )
86 {
87 Hybrid::forEach( std::make_index_sequence< Grid::dimension+1 >{},
88 [ & ]( auto i ){ if( i == this->codimension() ) this->template resize< i >( value ); } );
89 }
90
91 void shrinkToFit () {}
92
93 void fill ( const Value &value ) { std::fill( begin(), end(), value ); }
94
95 void swap ( This &other )
96 {
97 std::swap( grid_, other.grid_ );
98 std::swap( codim_, other.codim_ );
99 std::swap( idSet_, other.idSet_ );
100 std::swap( data_, other.data_ );
101 }
102
103 ConstIterator begin () const;
104 Iterator begin ();
105
106 ConstIterator end () const;
107 Iterator end ();
108
109 int codimension () const { return codim_; }
110
111 protected:
112 const Grid &grid () const { return *grid_; }
113
114 template< int codim >
115 void resize ( const Value &value );
116
117 template< int codim >
118 void migrateLevel ( int level, const Value &value, Map &data,
119 std::integral_constant< bool, true > );
120
121 template< int codim >
122 void migrateLevel ( int level, const Value &value, Map &data,
123 std::integral_constant< bool, false > );
124
125 static void migrateEntry ( const typename IdSet::IdType &id, const Value &value,
126 Map &oldData, Map &newData );
127
128 const IdSet &idSet () const { return *idSet_; }
129
130 const Grid *grid_;
131 int codim_;
132 const IdSet *idSet_;
133 Map data_;
134 };
135
136
137
138 // PersistentContainerMap::IteratorWrapper
139 // ---------------------------------------
140
141 template< class G, class IdSet, class Map >
142 template< class value, class iterator >
144 : public iterator
145 {
146 typedef IteratorWrapper< const value, typename Map::const_iterator > ConstWrapper;
147
148 public:
149 IteratorWrapper ( const iterator &it ) : it_( it ) {}
150
151 operator ConstWrapper () const { return ConstWrapper( it_ ); }
152
153 value &operator* () { return it_->second; }
154 value *operator-> () { return &(it_->second); }
155
156 bool operator== ( const IteratorWrapper &other ) const { return (it_ == other.it_); }
157 bool operator!= ( const IteratorWrapper &other ) const { return (it_ != other.it_); }
158
159 IteratorWrapper &operator++ () { ++it_; return *this; }
160
161 private:
162 iterator it_;
163 };
164
165
166
167
168 // Implementation of PersistentContainerMap
169 // ----------------------------------------
170
171 template< class G, class IdSet, class Map >
172 inline typename PersistentContainerMap< G, IdSet, Map >::ConstIterator
173 PersistentContainerMap< G, IdSet, Map >::begin () const
174 {
175 return ConstIterator( data_.begin() );
176 }
177
178 template< class G, class IdSet, class Map >
179 inline typename PersistentContainerMap< G, IdSet, Map >::Iterator
180 PersistentContainerMap< G, IdSet, Map >::begin ()
181 {
182 return Iterator( data_.begin() );
183 }
184
185
186 template< class G, class IdSet, class Map >
187 inline typename PersistentContainerMap< G, IdSet, Map >::ConstIterator
188 PersistentContainerMap< G, IdSet, Map >::end () const
189 {
190 return ConstIterator( data_.end() );
191 }
192
193 template< class G, class IdSet, class Map >
194 inline typename PersistentContainerMap< G, IdSet, Map >::Iterator
195 PersistentContainerMap< G, IdSet, Map >::end ()
196 {
197 return Iterator( data_.end() );
198 }
199
200
201 template< class G, class IdSet, class Map >
202 template< int codim >
203 inline void PersistentContainerMap< G, IdSet, Map >::resize ( const Value &value )
204 {
205 std::integral_constant< bool, Capabilities::hasEntityIterator< Grid, codim >::v > hasEntityIterator;
206 assert( codim == codimension() );
207
208 // create empty map and swap it with current map (no need to copy twice)
209 Map data;
210 std::swap( data, data_ );
211
212 // copy all data from old map into new one (adding new entries, if necessary)
213 const int maxLevel = grid().maxLevel();
214 for ( int level = 0; level <= maxLevel; ++level )
215 migrateLevel< codim >( level, value, data, hasEntityIterator );
216 }
217
218
219 template< class G, class IdSet, class Map >
220 template< int codim >
221 inline void PersistentContainerMap< G, IdSet, Map >
222 ::migrateLevel ( int level, const Value &value, Map &data,
223 std::integral_constant< bool, true > )
224 {
225 typedef typename Grid::LevelGridView LevelView;
226 typedef typename LevelView::template Codim< codim >::Iterator LevelIterator;
227
228 const LevelView levelView = grid().levelGridView( level );
229 const LevelIterator end = levelView.template end< codim >();
230 for( LevelIterator it = levelView.template begin< codim >(); it != end; ++it )
231 migrateEntry( idSet().id( *it ), value, data, data_ );
232 }
233
234
235 template< class G, class IdSet, class Map >
236 template< int codim >
237 inline void PersistentContainerMap< G, IdSet, Map >
238 ::migrateLevel ( int level, const Value &value, Map &data,
239 std::integral_constant< bool, false > )
240 {
241 typedef typename Grid::LevelGridView LevelView;
242 typedef typename LevelView::template Codim< 0 >::Iterator LevelIterator;
243
244 const LevelView levelView = grid().levelGridView( level );
245 const LevelIterator end = levelView.template end< 0 >();
246 for( LevelIterator it = levelView.template begin< 0 >(); it != end; ++it )
247 {
248 const typename LevelIterator::Entity &entity = *it;
249 const int subEntities = entity.subEntities( codim );
250 for( int i = 0; i < subEntities; ++i )
251 migrateEntry( idSet().subId( entity, i, codim ), value, data, data_ );
252 }
253 }
254
255
256 template< class G, class IdSet, class Map >
257 inline void PersistentContainerMap< G, IdSet, Map >
258 ::migrateEntry ( const typename IdSet::IdType &id, const Value &value,
259 Map &oldData, Map &newData )
260 {
261 // insert entry for id
262 const std::pair< typename Map::iterator, bool > inserted
263 = newData.insert( std::make_pair( id, value ) );
264
265 // if entry did not exist previously, copy data
266 if( inserted.second )
267 {
268 const typename Map::iterator pos = oldData.find( id );
269 if( pos != oldData.end() )
270 {
271 inserted.first->second = pos->second;
272 oldData.erase( pos );
273 }
274 }
275 }
276
277} // namespace Dune
278
279#endif // #ifndef DUNE_PERSISTENTCONTAINERMAP_HH
Wrapper class for entities.
Definition: entity.hh:64
@ codimension
Know your own codimension.
Definition: entity.hh:105
GridFamily::Traits::LevelGridView LevelGridView
type of view for level grid
Definition: grid.hh:405
Id Set Interface.
Definition: indexidset.hh:450
IdTypeImp IdType
Type used to represent an id.
Definition: indexidset.hh:456
map-based implementation of the PersistentContainer
Definition: persistentcontainermap.hh:24
A set of traits classes to store static information about grid implementation.
Traits for type conversions and type information.
constexpr void forEach(Range &&range, F &&f)
Range based for loop.
Definition: hybridutilities.hh:266
EnableIfInterOperable< T1, T2, bool >::type operator==(const ForwardIteratorFacade< T1, V1, R1, D > &lhs, const ForwardIteratorFacade< T2, V2, R2, D > &rhs)
Checks for equality.
Definition: iteratorfacades.hh:235
EnableIfInterOperable< T1, T2, bool >::type operator!=(const ForwardIteratorFacade< T1, V1, R1, D > &lhs, const ForwardIteratorFacade< T2, V2, R2, D > &rhs)
Checks for inequality.
Definition: iteratorfacades.hh:257
Dune namespace.
Definition: alignedallocator.hh:11
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Jul 24, 22:29, 2024)