opm-common
Loading...
Searching...
No Matches
FastSmallVector.hpp
Go to the documentation of this file.
1// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2// vi: set et ts=4 sw=4 sts=4:
3/*
4 Copyright 2019, 2025 Equinor ASA.
5
6 This file is part of the Open Porous Media project (OPM).
7
8 OPM is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 2 of the License, or
11 (at your option) any later version.
12
13 OPM is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with OPM. If not, see <http://www.gnu.org/licenses/>.
20
21 Consult the COPYING file in the top-level source directory of this
22 module for the precise wording of the license and the list of
23 copyright holders.
24*/
33#ifndef OPM_FAST_SMALL_VECTOR_HPP
34#define OPM_FAST_SMALL_VECTOR_HPP
35
36#include <array>
37#include <algorithm>
38#include <vector>
39
40namespace Opm {
41
48template <typename ValueType, unsigned N>
50{
51public:
54 : size_(0)
55 {
56 dataPtr_ = smallBuf_.data();
57 }
58
60 explicit FastSmallVector(const size_t numElem)
61 {
62 init_(numElem);
63 }
64
67 FastSmallVector(const size_t numElem, const ValueType value)
68 {
69 init_(numElem);
70
71 std::fill_n(dataPtr_, size_, value);
72 }
73
76 : size_(0)
77 {
78 dataPtr_ = smallBuf_.data();
79
80 (*this) = other;
81 }
82
85 : size_(0)
86 {
87 dataPtr_ = smallBuf_.data();
88
89 (*this) = std::move(other);
90 }
91
94 {
95 }
96
97
100 {
101 size_ = other.size_;
102 if (other.usingSmallBuf()) {
103 smallBuf_ = std::move(other.smallBuf_);
104 dataPtr_ = smallBuf_.data();
105 }
106 else {
107 data_ = std::move(other.data_);
108 dataPtr_ = data_.data();
109 }
110
111 other.dataPtr_ = nullptr;
112 other.size_ = 0;
113
114 return (*this);
115 }
116
119 {
120 size_ = other.size_;
121
122 if (other.usingSmallBuf()) {
123 smallBuf_ = other.smallBuf_;
124 dataPtr_ = smallBuf_.data();
125 }
126 else if (dataPtr_ != other.dataPtr_) {
127 data_ = other.data_;
128 dataPtr_ = data_.data();
129 }
130
131 return (*this);
132 }
133
135 ValueType& operator[](size_t idx)
136 { return dataPtr_[idx]; }
137
139 const ValueType& operator[](size_t idx) const
140 { return dataPtr_[idx]; }
141
142 using size_type = typename std::vector<ValueType>::size_type;
143
145 size_type size() const
146 { return size_; }
147
149 using Iterator = ValueType*;
150
152 using ConstIterator = const ValueType*;
153
156 { return dataPtr_; }
157
160 { return dataPtr_ + size_; }
161
164 { return dataPtr_; }
165
168 { return dataPtr_ + size_; }
169
172 { return dataPtr_; }
173
176 { return dataPtr_ + size_; }
177
178 size_type capacity()
179 { return this->usingSmallBuf() ? N : data_.capacity(); }
180
181 void push_back(const ValueType& value)
182 {
183 if (this->usingSmallBuf()) {
184 if (size_ < N) {
185 // Data is contained in smallBuf_
186 smallBuf_[size_++] = value;
187 } else if (size_ == N) {
188 // Must switch from using smallBuf_ to using data_
189 data_.reserve(N + 1); // Since we will push_back to it later
190 data_.resize(N); // So we can move the existing data to it
191 std::move(smallBuf_.begin(), smallBuf_.end(), data_.begin());
192 data_.push_back(value);
193 ++size_;
194 dataPtr_ = data_.data();
195 }
196 } else {
197 // Data is contained in data_
198 data_.push_back(value);
199 ++size_;
200 dataPtr_ = data_.data();
201 }
202 }
203
204 void resize(size_t numElem)
205 {
206 if (numElem == size_) return; // nothing to do
207
208 if (this->usingSmallBuf()) {
209 if (numElem > N) {
210 data_.resize(numElem);
211 if (size_ > 0 && N > 0) {
212 std::copy_n(smallBuf_.begin(), size_, data_.begin());
213 }
214 dataPtr_ = data_.data();
215 } else if (numElem < size_) {
216 // when shrinking, remove the values after numElem so that the space
217 // is ready to use in the potentional future resize
218 for (auto ii = numElem; ii < size_; ++ii) {
219 smallBuf_[ii].~ValueType();
220 }
221 }
222 } else {
223 // when shriking to numElem < N, we do not switch back to use smallBuf_
224 data_.resize(numElem);
225 }
226 size_ = numElem;
227 }
228
229private:
230 void init_(size_t numElem)
231 {
232 size_ = numElem;
233
234 if (size_ > N) {
235 data_.resize(size_);
236 dataPtr_ = data_.data();
237 } else
238 dataPtr_ = smallBuf_.data();
239 }
240
241 bool usingSmallBuf() const
242 {
243 return dataPtr_ == smallBuf_.data();
244 }
245
246 std::array<ValueType, N> smallBuf_{};
247 std::vector<ValueType> data_;
248 size_type size_;
249 ValueType* dataPtr_;
250};
251
252} // namespace Opm
253
254#endif // OPM_FAST_SMALL_VECTOR_HPP
FastSmallVector()
default constructor
Definition FastSmallVector.hpp:53
Iterator end()
To support range-for etc.
Definition FastSmallVector.hpp:175
const ValueType * ConstIterator
ConstIterator type is a plain pointer, so be warned there is no validity checking.
Definition FastSmallVector.hpp:152
FastSmallVector & operator=(FastSmallVector &&other)
move assignment
Definition FastSmallVector.hpp:99
FastSmallVector(FastSmallVector &&other)
move constructor
Definition FastSmallVector.hpp:84
ConstIterator end() const
To support range-for etc.
Definition FastSmallVector.hpp:159
const ValueType & operator[](size_t idx) const
const access the idx th element
Definition FastSmallVector.hpp:139
ValueType * Iterator
Iterator type is a plain pointer, so be warned there is no validity checking.
Definition FastSmallVector.hpp:149
FastSmallVector(const size_t numElem, const ValueType value)
constructor based on the number of the element, and all the elements will have the same value
Definition FastSmallVector.hpp:67
FastSmallVector & operator=(const FastSmallVector &other)
copy assignment
Definition FastSmallVector.hpp:118
~FastSmallVector()
destructor
Definition FastSmallVector.hpp:93
FastSmallVector(const size_t numElem)
constructor based on the number of the element
Definition FastSmallVector.hpp:60
FastSmallVector(const FastSmallVector &other)
copy constructor
Definition FastSmallVector.hpp:75
ConstIterator cbegin() const
To support range-for etc.
Definition FastSmallVector.hpp:163
ConstIterator begin() const
To support range-for etc.
Definition FastSmallVector.hpp:155
ConstIterator cend() const
To support range-for etc.
Definition FastSmallVector.hpp:167
ValueType & operator[](size_t idx)
access the idx th element
Definition FastSmallVector.hpp:135
size_type size() const
number of elements
Definition FastSmallVector.hpp:145
Iterator begin()
To support range-for etc.
Definition FastSmallVector.hpp:171
This class implements a small container which holds the transmissibility mulitpliers for all the face...
Definition Exceptions.hpp:30