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 
17 namespace 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
constexpr static 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.
concept Grid
Requirements for implementations of the Dune::Grid interface.
Definition: grid.hh:98
concept Entity
Model of a grid entity.
Definition: entity.hh:107
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 inequality.
Definition: iteratorfacades.hh:259
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:237
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.80.0 (May 1, 22:29, 2024)