libMesh
Loading...
Searching...
No Matches
chunked_mapvector.h
Go to the documentation of this file.
1// The libMesh Finite Element Library.
2// Copyright (C) 2002-2026 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
3
4// This library is free software; you can redistribute it and/or
5// modify it under the terms of the GNU Lesser General Public
6// License as published by the Free Software Foundation; either
7// version 2.1 of the License, or (at your option) any later version.
8
9// This library is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12// Lesser General Public License for more details.
13
14// You should have received a copy of the GNU Lesser General Public
15// License along with this library; if not, write to the Free Software
16// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
18
19
20#ifndef LIBMESH_CHUNKED_MAPVECTOR_H
21#define LIBMESH_CHUNKED_MAPVECTOR_H
22
23// C++ Includes -----------------------------------
24#include <map>
25
26namespace libMesh
27{
28
42template <typename Val, typename index_t=unsigned int, unsigned int N=16>
43class chunked_mapvector : public std::map<index_t, std::array<Val,N>>
44{
45public:
46 typedef std::map<index_t, std::array<Val,N>> maptype;
47
48 typedef unsigned int iter_t; // Only has to hold 0 through N
49
50 template <typename MapIter>
52 {
53 public:
54 veclike_iterator_base(const MapIter & i,
55 const iter_t idx)
56 : it(i), array_index(idx) {}
57
59
60 template <typename T>
63
65 {
67 if (array_index >= N)
68 {
69 array_index = 0;
70 ++it;
71 }
72 return *this;
73 }
74
76 {
77 veclike_iterator i = *this;
78 ++(*this);
79 return i;
80 }
81
82 bool operator==(const veclike_iterator_base & other) const
83 {
84 return (it == other.it && array_index == other.array_index);
85 }
86
87 bool operator!=(const veclike_iterator_base & other) const
88 {
89 return (it != other.it || array_index != other.array_index);
90 }
91
92 index_t index() const { return this->it->first * N + this->array_index; }
93
94 private:
95 friend class chunked_mapvector;
96
97 MapIter it;
98
100 };
101
103 public veclike_iterator_base<typename maptype::iterator>
104 {
105 public:
106 veclike_iterator(const typename maptype::iterator & i,
107 const iter_t idx)
108 : veclike_iterator_base<typename maptype::iterator>(i,idx) {}
109
110 Val & operator*() const { return (this->it->second)[this->array_index]; }
111
112 Val * operator->() const { return &((this->it->second)[this->array_index]); }
113 };
114
115
117 public veclike_iterator_base<typename maptype::const_iterator>
118 {
119 public:
120 const_veclike_iterator(const typename maptype::const_iterator & i,
121 const iter_t idx)
122 : veclike_iterator_base<typename maptype::const_iterator>(i,idx) {}
123
124 const Val & operator*() const { return (this->it->second)[this->array_index]; }
125
126 const Val * operator->() const { return &((this->it->second)[this->array_index]); }
127 };
128
130 {
131 public:
132 const_reverse_veclike_iterator(const typename maptype::const_reverse_iterator & i,
133 const iter_t idx)
134 : it(i), array_index(idx) {}
135
137
139 {
140 if (array_index == 0)
141 {
142 array_index = N-1;
143 ++it;
144 }
145 else
146 --array_index;
147 return *this;
148 }
149
151 {
152 veclike_iterator i = *this;
153 ++(*this);
154 return i;
155 }
156
157 const Val & operator*() const { return (this->it->second)[this->array_index]; }
158
159 const Val * operator->() const { return &((this->it->second)[this->array_index]); }
160
161 index_t index() const { return this->it->first * N + this->array_index; }
162
164 {
165 return (it == other.it && array_index == other.array_index);
166 }
167
169 {
170 return (it != other.it || array_index != other.array_index);
171 }
172
173 private:
174 typename maptype::const_reverse_iterator it;
175
177 };
178
179 veclike_iterator find (const index_t & k)
180 {
181 auto sub_it = maptype::find(k/N);
182 if (sub_it == maptype::end())
183 return veclike_iterator(sub_it, 0);
184
185 veclike_iterator it {sub_it, iter_t(k%N)};
186 if (*it)
187 return it;
188 return this->end();
189 }
190
191 const_veclike_iterator find (const index_t & k) const
192 {
193 auto sub_it = maptype::find(k/N);
194 if (sub_it == maptype::end())
195 return const_veclike_iterator(sub_it, 0);
196
197 const_veclike_iterator it {sub_it, iter_t(k%N)};
198 if (*it)
199 return it;
200 return this->end();
201 }
202
203 Val & operator[] (const index_t & k)
204 {
205 return maptype::operator[](k/N)[k%N];
206 }
207
208 Val operator[] (const index_t & k) const
209 {
210 typename maptype::const_iterator it = maptype::find(k/N);
211 return it == this->end().it? Val() : (it->second)[k%N];
212 }
213
214 void erase(index_t i)
215 {
216 typename maptype::iterator it = maptype::find(i/N);
217 if (it == maptype::end())
218 return;
219
220 (it->second)[i%N] = Val();
221 for (auto v : it->second)
222 if (v != Val())
223 return;
224
225 maptype::erase(it);
226 }
227
229 {
230 if (pos.it == maptype::end())
231 return pos;
232 *pos = Val();
233
234 veclike_iterator newpos = pos;
235 do {
236 ++newpos;
237 } while (newpos.it == pos.it &&
238 *newpos == Val());
239
240 for (auto v : pos.it->second)
241 if (v != Val())
242 return newpos;
243
244 maptype::erase(pos.it);
245
246 return newpos;
247 }
248
250 {
251 return veclike_iterator(maptype::begin(), 0);
252 }
253
255 {
256 return const_veclike_iterator(maptype::begin(), 0);
257 }
258
260 {
261 return veclike_iterator(maptype::end(), 0);
262 }
263
265 {
266 return const_veclike_iterator(maptype::end(), 0);
267 }
268
270 {
271 return const_reverse_veclike_iterator(maptype::rbegin(), N-1);
272 }
273
275 {
276 return const_reverse_veclike_iterator(maptype::rend(), N-1);
277 }
278};
279
280} // namespace libMesh
281
282#endif // LIBMESH_CHUNKED_MAPVECTOR_H
bool operator==(const const_reverse_veclike_iterator &other) const
const_reverse_veclike_iterator(const typename maptype::const_reverse_iterator &i, const iter_t idx)
const_reverse_veclike_iterator(const const_reverse_veclike_iterator &i)=default
bool operator!=(const const_reverse_veclike_iterator &other) const
const_veclike_iterator(const typename maptype::const_iterator &i, const iter_t idx)
veclike_iterator_base(const veclike_iterator_base &i)=default
veclike_iterator_base(const MapIter &i, const iter_t idx)
bool operator!=(const veclike_iterator_base &other) const
veclike_iterator_base(const veclike_iterator_base< T > &i)
bool operator==(const veclike_iterator_base &other) const
veclike_iterator(const typename maptype::iterator &i, const iter_t idx)
This chunked_mapvector templated class is intended to provide the asymptotic performance characterist...
const_reverse_veclike_iterator rbegin() const
const_reverse_veclike_iterator rend() const
veclike_iterator erase(const veclike_iterator &pos)
Val & operator[](const index_t &k)
veclike_iterator find(const index_t &k)
const_veclike_iterator end() const
const_veclike_iterator begin() const
const_veclike_iterator find(const index_t &k) const
std::map< index_t, std::array< Val, N > > maptype
The libMesh namespace provides an interface to certain functionality in the library.