Block-Structured AMR Software Framework
 
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
Loading...
Searching...
No Matches
AMReX_Vector.H
Go to the documentation of this file.
1#ifndef AMREX_VECTOR_H_
2#define AMREX_VECTOR_H_
3#include <AMReX_Config.H>
4
5#include <AMReX_BLassert.H>
6#include <AMReX_Extension.H>
7#include <AMReX_INT.H>
8#ifdef AMREX_SPACEDIM
9#include <AMReX_Array.H>
10#include <AMReX_TypeTraits.H>
11#endif
12
13#include <algorithm>
14#include <memory>
15#include <vector>
16
17namespace amrex {
23template <class T, class Allocator=std::allocator<T> >
24class Vector
25 :
26 public std::vector<T, Allocator>
27{
28public:
29
30 using std::vector<T, Allocator>::vector;
31 using typename std::vector<T, Allocator>::size_type;
32
33 [[nodiscard]] T& operator[] (size_type i) noexcept
34 {
35 BL_ASSERT( i < (this->std::vector<T, Allocator>::size()) );
36 return this->std::vector<T, Allocator>::operator[](i);
37 }
38
39 [[nodiscard]] const T& operator[] (size_type i) const noexcept
40 {
41 BL_ASSERT( i < (this->std::vector<T, Allocator>::size()) );
42 return this->std::vector<T, Allocator>::operator[](i);
43 }
44
46 [[nodiscard]] T* dataPtr () noexcept { return this->data(); }
48 [[nodiscard]] const T* dataPtr () const noexcept { return this->data(); }
49
50 [[nodiscard]] Long size () const noexcept {return static_cast<Long>(std::vector<T, Allocator>::size());}
51
52};
53
54}
55
56namespace amrex
57{
59
60 template <class T, typename = typename T::FABType>
62 {
64 r.reserve(a.size());
65 for (auto& x : a) { r.push_back(&x); }
66 return r;
67 }
68
69 template <class T, std::size_t N, typename = typename T::FABType>
71 {
73 r.reserve(a.size());
74 for (auto& x : a) { r.push_back(&x); }
75 return r;
76 }
77
78 template <class T>
79 [[nodiscard]] Vector<T*> GetVecOfPtrs (const Vector<std::unique_ptr<T> >& a)
80 {
82 r.reserve(a.size());
83 for (const auto& x : a) { r.push_back(x.get()); }
84 return r;
85 }
86
88
89 template <class T, typename = typename T::FABType>
91 {
93 r.reserve(a.size());
94 for (const auto& x : a) { r.push_back(&x); }
95 return r;
96 }
97
98 template <class T, std::size_t N, typename = typename T::FABType>
99 [[nodiscard]] Vector<Array<T,N> const*> GetVecOfConstPtrs (Vector<Array<T,N>> const& a)
100 {
101 Vector<Array<T,N> const*> r;
102 r.reserve(a.size());
103 for (auto& x : a) { r.push_back(&x); }
104 return r;
105 }
106
107 template <class T>
108 [[nodiscard]] Vector<const T*> GetVecOfConstPtrs (const Vector<std::unique_ptr<T> >& a)
109 {
111 r.reserve(a.size());
112 for (const auto& x : a) { r.push_back(x.get()); }
113 return r;
114 }
115
116 template <class T, typename = typename T::FABType>
118 {
119 return {a.begin(), a.end()};
120 }
121
123
124 template <class T>
125 [[nodiscard]] Vector<Vector<T*> > GetVecOfVecOfPtrs (const Vector<Vector<std::unique_ptr<T> > >& a)
126 {
128 r.reserve(a.size());
129 for (const auto& x : a) { r.push_back(GetVecOfPtrs(x)); }
130 return r;
131 }
132
134
135#ifdef AMREX_SPACEDIM
136 template <class T>
137 [[nodiscard]] Vector<std::array<T*,AMREX_SPACEDIM> >
138 GetVecOfArrOfPtrs (const Vector<std::array<std::unique_ptr<T>,AMREX_SPACEDIM> >& a)
139 {
141 r.reserve(a.size());
142 for (const auto& x : a) { r.push_back(GetArrOfPtrs(x)); }
143 return r;
144 }
145
146 template <class T>
147 [[nodiscard]] Vector<std::array<T const*,AMREX_SPACEDIM> >
148 GetVecOfArrOfPtrsConst (const Vector<std::array<std::unique_ptr<T>,AMREX_SPACEDIM> >& a)
149 {
151 r.reserve(a.size());
152 for (const auto& x : a) { r.push_back(GetArrOfConstPtrs(x)); }
153 return r;
154 }
155
156 template <class T>
157 [[nodiscard]] Vector<std::array<T const*,AMREX_SPACEDIM> >
158 GetVecOfArrOfConstPtrs (const Vector<std::array<std::unique_ptr<T>,AMREX_SPACEDIM> >& a)
159 {
161 r.reserve(a.size());
162 for (const auto& x : a) { r.push_back(GetArrOfConstPtrs(x)); }
163 return r;
164 }
165
166 template <class T, std::enable_if_t<IsFabArray<T>::value ||
167 IsBaseFab<T>::value,
168 int> = 0 >
169 [[nodiscard]] Vector<std::array<T const*,AMREX_SPACEDIM> >
170 GetVecOfArrOfConstPtrs (const Vector<std::array<T,AMREX_SPACEDIM> >& a)
171 {
173 r.reserve(a.size());
174 for (const auto& x : a) { r.push_back(GetArrOfConstPtrs(x)); }
175 return r;
176 }
177
178 template <class T, std::enable_if_t<IsFabArray<T>::value ||
179 IsBaseFab<T>::value,
180 int> = 0 >
181 [[nodiscard]] Vector<std::array<T*, AMREX_SPACEDIM> >
182 GetVecOfArrOfPtrs(Vector<std::array<T, AMREX_SPACEDIM> >& a)
183 {
185 r.reserve(a.size());
186 for (auto &x: a) { r.push_back(GetArrOfPtrs(x)); }
187 return r;
188 }
189#endif
190
192
193 template <class T>
195 {
196 std::for_each(a.begin(), a.end(), [](T*& p) { p = nullptr; });
197 }
198
199 template <class T>
200 void FillNull (Vector<std::unique_ptr<T> >& a)
201 {
202 std::for_each(a.begin(), a.end(), [](std::unique_ptr<T>& p) { p.reset(); });
203 }
204
206
207 template <class T>
209 std::sort(vec.begin(), vec.end());
210 auto it = std::unique(vec.begin(), vec.end());
211 vec.erase(it, vec.end());
212 }
213
214 namespace detail {
215 template <class T, class H>
216 std::size_t removeDupDoit (Vector<T>& vec, std::size_t start, std::size_t stop)
217 {
218 std::size_t N = stop-start;
219 if (N < 2) { return stop; }
220
221 T* const data = vec.data() + start;
222 T const sentinel = data[0]; // duplicates will be set to sentinel and removed later
223 H const hasher;
224 for (std::size_t i = 1; i < N; ) {
225 if (data[i] == sentinel) {
226 ++i;
227 continue;
228 }
229
230 std::size_t const hash = hasher(data[i]) % N;
231 if (i == hash) { // data[i] in correct hash position
232 ++i;
233 continue;
234 }
235
236 if (data[i] == data[hash]) {
237 data[i] = sentinel; // because it's a duplicate
238 ++i;
239 continue;
240 }
241
242 if (data[hash] == sentinel) {
243 std::swap(data[hash], data[i]);
244 // after swap, new data[i] holds sentinel
245 // newdata[hash] in correct hash poitiion
246 ++i;
247 continue;
248 }
249
250 std::size_t const hashhash = hasher(data[hash]) % N;
251 if (hashhash != hash) { // data[hash] not in correct has poision, thus will yield it's position
252 std::swap(data[i], data[hash]);
253 // after swap, new data[hash] in correct hash position
254 // new data[i] not sure
255 if (hash < i) { // we have seen new data[i]
256 ++i;
257 } // else next iteration we will work on data[i]
258 } else { // data[hash] in correct hash position, but data[i] is not because of hash collision
259 ++i;
260 }
261 }
262
263 // Now there are three types for data[i]
264 // (1) sentinel
265 // (2) data[i] != sentinel and hash(data[i]) == i
266 // (3) data[i] != sentinel and hash(data[i]) != i because of hash collision
267 // All type 2s are unique, and all sentinels except one can be removed.
268 // We will move all type 2s to the beginning, all sentinels to the end.
269 // This will leave all type 3s in the middle. Then we will work on the middle
270 // part plus one sentinel.
271
272 std::size_t swapPos = 0;
273 for (std::size_t i = 0; i < N; ++i) {
274 // move type 2 to the beginning pointed to by swapPos
275 if (data[i] != sentinel && i == hasher(data[i]) % N) {
276 std::swap(data[i], data[swapPos++]);
277 }
278 }
279
280 // Now we have moved all type 2 elements to the beginning, [0,swapPos)
281
282 std::size_t sentinelPos = N;
283 for (std::size_t i = swapPos; i < sentinelPos; ) {
284 // move type 1 to the end
285 if(data[i] == sentinel) {
286 std::swap(data[i], data[--sentinelPos]);
287 } else {
288 ++i;
289 }
290 }
291
292 // recursively work on the middle part
293 return detail::removeDupDoit<T,H>(vec, start+swapPos, start+sentinelPos+1);
294 }
295 }
296
297 template <class T, class H>
299 // https://stackoverflow.com/questions/1532819/algorithm-efficient-way-to-remove-duplicate-integers-from-an-array
300 std::size_t pos = detail::removeDupDoit<T,H>(vec, 0, vec.size());
301 vec.erase(vec.begin()+pos, vec.end());
302 }
303}
304
305#endif
#define BL_ASSERT(EX)
Definition AMReX_BLassert.H:39
This class is a thin wrapper around std::vector. Unlike vector, Vector::operator[] provides bound che...
Definition AMReX_Vector.H:27
T & operator[](size_type i) noexcept
Definition AMReX_Vector.H:33
T * dataPtr() noexcept
get access to the underlying data pointer
Definition AMReX_Vector.H:46
Long size() const noexcept
Definition AMReX_Vector.H:50
const T * dataPtr() const noexcept
get access to the underlying data pointer
Definition AMReX_Vector.H:48
std::size_t removeDupDoit(Vector< T > &vec, std::size_t start, std::size_t stop)
Definition AMReX_Vector.H:216
Definition AMReX_Amr.cpp:49
Vector< std::array< T const *, AMREX_SPACEDIM > > GetVecOfArrOfConstPtrs(const Vector< std::array< std::unique_ptr< T >, AMREX_SPACEDIM > > &a)
Definition AMReX_Vector.H:158
Vector< const T * > GetVecOfConstPtrs(const Vector< T > &a)
Definition AMReX_Vector.H:90
Vector< std::array< T *, AMREX_SPACEDIM > > GetVecOfArrOfPtrs(const Vector< std::array< std::unique_ptr< T >, AMREX_SPACEDIM > > &a)
Definition AMReX_Vector.H:138
Vector< T * > GetVecOfPtrs(Vector< T > &a)
Definition AMReX_Vector.H:61
std::array< T *, AMREX_SPACEDIM > GetArrOfPtrs(std::array< T, AMREX_SPACEDIM > &a) noexcept
Definition AMReX_Array.H:966
void FillNull(Vector< T * > &a)
Definition AMReX_Vector.H:194
Vector< Vector< T * > > GetVecOfVecOfPtrs(const Vector< Vector< std::unique_ptr< T > > > &a)
Definition AMReX_Vector.H:125
std::array< T const *, AMREX_SPACEDIM > GetArrOfConstPtrs(const std::array< T, AMREX_SPACEDIM > &a) noexcept
Definition AMReX_Array.H:978
Vector< std::array< T const *, AMREX_SPACEDIM > > GetVecOfArrOfPtrsConst(const Vector< std::array< std::unique_ptr< T >, AMREX_SPACEDIM > > &a)
Definition AMReX_Vector.H:148
void RemoveDuplicates(Vector< T > &vec)
Definition AMReX_Vector.H:208
std::array< T, N > Array
Definition AMReX_Array.H:24
Definition AMReX_FabArrayCommI.H:896