Dune Core Modules (unstable)

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