Line data Source code
1 : // EnergyPlus, Copyright (c) 1996-2025, The Board of Trustees of the University of Illinois,
2 : // The Regents of the University of California, through Lawrence Berkeley National Laboratory
3 : // (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge
4 : // National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other
5 : // contributors. All rights reserved.
6 : //
7 : // NOTICE: This Software was developed under funding from the U.S. Department of Energy and the
8 : // U.S. Government consequently retains certain rights. As such, the U.S. Government has been
9 : // granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable,
10 : // worldwide license in the Software to reproduce, distribute copies to the public, prepare
11 : // derivative works, and perform publicly and display publicly, and to permit others to do so.
12 : //
13 : // Redistribution and use in source and binary forms, with or without modification, are permitted
14 : // provided that the following conditions are met:
15 : //
16 : // (1) Redistributions of source code must retain the above copyright notice, this list of
17 : // conditions and the following disclaimer.
18 : //
19 : // (2) Redistributions in binary form must reproduce the above copyright notice, this list of
20 : // conditions and the following disclaimer in the documentation and/or other materials
21 : // provided with the distribution.
22 : //
23 : // (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory,
24 : // the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be
25 : // used to endorse or promote products derived from this software without specific prior
26 : // written permission.
27 : //
28 : // (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form
29 : // without changes from the version obtained under this License, or (ii) Licensee makes a
30 : // reference solely to the software portion of its product, Licensee must refer to the
31 : // software as "EnergyPlus version X" software, where "X" is the version number Licensee
32 : // obtained under this License and may not use a different name for the software. Except as
33 : // specifically required in this Section (4), Licensee shall not use in a company name, a
34 : // product name, in advertising, publicity, or other promotional activities any name, trade
35 : // name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly
36 : // similar designation, without the U.S. Department of Energy's prior written consent.
37 : //
38 : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
39 : // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
40 : // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
41 : // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
42 : // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
43 : // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
44 : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
45 : // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
46 : // POSSIBILITY OF SUCH DAMAGE.
47 :
48 : #ifndef EPVector_hh_INCLUDED
49 : #define EPVector_hh_INCLUDED
50 :
51 : #include <numeric>
52 : #include <vector>
53 :
54 : #include <EnergyPlus/EnergyPlus.hh>
55 :
56 : namespace EnergyPlus {
57 :
58 : template <typename T> struct EPVector : private std::vector<T>
59 : {
60 : using std::vector<T>::size;
61 : #ifdef NDEBUG
62 : using std::vector<T>::operator[];
63 : #endif
64 : using std::vector<T>::empty;
65 : using std::vector<T>::begin;
66 : using std::vector<T>::end;
67 : using std::vector<T>::cbegin;
68 : using std::vector<T>::cend;
69 : using std::vector<T>::emplace_back;
70 : using std::vector<T>::push_back;
71 : using const_iterator = typename std::vector<T>::const_iterator;
72 :
73 : using value_type = T;
74 : using size_type = typename std::vector<T>::size_type;
75 :
76 : #ifndef NDEBUG
77 411566702 : [[nodiscard]] T &operator[](size_type n)
78 : {
79 411566702 : return std::vector<T>::at(n);
80 : }
81 :
82 4963404 : [[nodiscard]] const T &operator[](size_type n) const
83 : {
84 4963404 : return std::vector<T>::at(n);
85 : }
86 : #endif
87 :
88 410733423 : [[nodiscard]] T &operator()(size_type n)
89 : {
90 410733423 : return (*this)[n - 1];
91 : }
92 :
93 4732451 : [[nodiscard]] const T &operator()(size_type n) const
94 : {
95 4732451 : return (*this)[n - 1];
96 : }
97 :
98 23251 : void allocate(size_type size)
99 : {
100 23251 : m_allocated = true;
101 23251 : std::vector<T>::resize(size);
102 23251 : std::fill(begin(), end(), T{});
103 35500 : }
104 :
105 177187 : void deallocate() noexcept
106 : {
107 177187 : m_allocated = false;
108 177187 : std::vector<T>::clear();
109 177187 : }
110 :
111 67370 : void clear() noexcept
112 : {
113 67370 : m_allocated = false;
114 67370 : std::vector<T>::clear();
115 67370 : }
116 :
117 2952 : void resize(size_type count)
118 : {
119 2952 : m_allocated = true;
120 2952 : std::vector<T>::resize(count);
121 2952 : }
122 :
123 226 : void resize(size_type count, const T &value)
124 : {
125 226 : m_allocated = true;
126 226 : std::vector<T>::resize(count, value);
127 226 : }
128 :
129 3212621 : [[nodiscard]] bool allocated() const noexcept
130 : {
131 3212621 : return m_allocated || !this->empty();
132 : }
133 :
134 : // operator= used for initialization of the vector
135 3267000 : void operator=(const T &v)
136 : {
137 3267000 : std::fill(this->begin(), this->end(), v);
138 3267000 : }
139 :
140 : // dimension is often used to initalize the vector instead of allocate + operator=
141 2625 : void dimension(std::size_t size, const T &v)
142 : {
143 2625 : std::vector<T>::clear();
144 2625 : std::vector<T>::resize(size, v);
145 2625 : }
146 :
147 : // isize needed for current FindItemInList
148 208130 : [[nodiscard]] int isize() const noexcept
149 : {
150 208130 : return static_cast<int>(this->size());
151 : }
152 :
153 : private:
154 : bool m_allocated{false};
155 : };
156 :
157 : template <> struct EPVector<bool> : private std::vector<std::uint8_t>
158 : {
159 : using std::vector<std::uint8_t>::size;
160 : #ifdef NDEBUG
161 : using std::vector<std::uint8_t>::operator[];
162 : #endif
163 : using std::vector<std::uint8_t>::empty;
164 : using std::vector<std::uint8_t>::begin;
165 : using std::vector<std::uint8_t>::end;
166 : using std::vector<std::uint8_t>::cbegin;
167 : using std::vector<std::uint8_t>::cend;
168 : using std::vector<std::uint8_t>::emplace_back;
169 : using std::vector<std::uint8_t>::push_back;
170 : using const_iterator = typename std::vector<std::uint8_t>::const_iterator;
171 :
172 : using value_type = std::uint8_t;
173 : using size_type = typename std::vector<std::uint8_t>::size_type;
174 :
175 : #ifndef NDEBUG
176 2830 : [[nodiscard]] std::uint8_t &operator[](std::size_t n)
177 : {
178 2830 : return std::vector<std::uint8_t>::at(n);
179 : }
180 :
181 : [[nodiscard]] const std::uint8_t &operator[](size_type n) const
182 : {
183 : return std::vector<std::uint8_t>::at(n);
184 : }
185 :
186 2825 : [[nodiscard]] std::uint8_t &operator()(size_type n)
187 : {
188 2825 : return (*this)[n - 1];
189 : }
190 :
191 : [[nodiscard]] const std::uint8_t &operator()(size_type n) const
192 : {
193 : return (*this)[n - 1];
194 : }
195 : #else
196 : [[nodiscard]] std::uint8_t &operator()(size_type n) noexcept
197 : {
198 : return (*this)[n - 1];
199 : }
200 :
201 : [[nodiscard]] const std::uint8_t &operator()(size_type n) const noexcept
202 : {
203 : return (*this)[n - 1];
204 : }
205 : #endif
206 :
207 4 : [[nodiscard]] bool allocated() const noexcept
208 : {
209 4 : return m_allocated || !this->empty();
210 : }
211 :
212 1 : void allocate(size_type size)
213 : {
214 1 : m_allocated = true;
215 1 : std::vector<std::uint8_t>::resize(size);
216 1 : std::fill(begin(), end(), false);
217 1 : }
218 :
219 1 : void deallocate() noexcept
220 : {
221 1 : m_allocated = false;
222 1 : std::vector<std::uint8_t>::clear();
223 1 : }
224 :
225 2 : void clear() noexcept
226 : {
227 2 : m_allocated = false;
228 2 : std::vector<std::uint8_t>::clear();
229 2 : }
230 :
231 3 : void resize(size_type count)
232 : {
233 3 : m_allocated = true;
234 3 : std::vector<std::uint8_t>::resize(count);
235 3 : }
236 :
237 450 : void resize(size_type count, const bool &value)
238 : {
239 450 : m_allocated = true;
240 450 : std::vector<std::uint8_t>::resize(count, value);
241 450 : }
242 :
243 : // operator= used for initialization of the vector
244 : void operator=(bool v)
245 : {
246 : std::fill(this->begin(), this->end(), v);
247 : }
248 :
249 : // dimension is often used to initalize the vector instead of allocate + operator=
250 : void dimension(std::size_t size, const bool v)
251 : {
252 : std::vector<std::uint8_t>::clear();
253 : std::vector<std::uint8_t>::resize(size, v);
254 : }
255 :
256 : // isize needed for current FindItemInList
257 : [[nodiscard]] int isize() const noexcept
258 : {
259 : return static_cast<int>(this->size());
260 : }
261 :
262 : private:
263 : bool m_allocated{false};
264 : };
265 :
266 3199499 : template <typename T>[[nodiscard]] bool allocated(EPVector<T> const &v) noexcept
267 : {
268 3199499 : return v.allocated();
269 : }
270 :
271 186 : template <typename T>[[nodiscard]] auto isize(const EPVector<T> &v) noexcept
272 : {
273 186 : return v.isize();
274 : }
275 :
276 : [[nodiscard]] inline bool all(EPVector<bool> const &values) noexcept
277 : {
278 : if (values.empty()) {
279 : return true;
280 : }
281 : return std::all_of(values.cbegin(), values.end(), [](bool v) { return v; });
282 : }
283 :
284 : [[nodiscard]] inline bool any(EPVector<bool> const &values) noexcept
285 : {
286 : if (values.empty()) {
287 : return false;
288 : }
289 : return std::any_of(values.cbegin(), values.end(), [](bool v) { return v; });
290 : }
291 :
292 : [[nodiscard]] inline std::size_t count(EPVector<bool> const &values) noexcept
293 : {
294 : return std::count_if(values.cbegin(), values.cend(), [](bool v) { return v; });
295 : }
296 :
297 : template <typename T>[[nodiscard]] EPVector<T> pack(EPVector<T> const &v, EPVector<bool> const &mask)
298 : {
299 : EPVector<T> r;
300 : r.reserve(mask.size());
301 : for (std::size_t i = 0; i < mask.size(); ++i) {
302 : if (mask[i]) {
303 : r.emplace_back(v[i]);
304 : }
305 : }
306 : return r;
307 : }
308 :
309 : template <typename T>[[nodiscard]] Array1D<T> pack(Array1<T> const &a, EPVector<bool> const &mask)
310 : {
311 : Array1D<T> r;
312 : r.reserve(mask.size());
313 : for (std::size_t i = 0, e = mask.size(); i < e; ++i) {
314 : if (mask[i]) {
315 : r.emplace_back(a[i]);
316 : }
317 : }
318 : return r;
319 : }
320 :
321 : template <typename T>[[nodiscard]] T magnitude_squared(const EPVector<T> &v)
322 : {
323 : return std::inner_product(v.begin(), v.end(), v.begin(), T{});
324 : }
325 :
326 : template <typename T, typename V>[[nodiscard]] T dot(const EPVector<T> &u, const V &v)
327 : {
328 : return std::inner_product(u.begin(), u.end(), v.begin(), T{});
329 : }
330 :
331 153 : template <typename Element, typename Member>[[nodiscard]] Member maxval(EPVector<Element> const &a, Member Element::*pmem)
332 : {
333 153 : Member v(a.empty() ? std::numeric_limits<Member>::lowest() : a(1).*pmem);
334 43146 : for (int i = 2, e = a.isize(); i <= e; ++i) {
335 42993 : v = std::max(v, a(i).*pmem);
336 : }
337 153 : return v;
338 : }
339 :
340 : // Sum of All Members of a Container
341 284 : template <typename Element, typename Member> inline Member sum(EPVector<Element> const &c, Member Element::*pmem)
342 : {
343 679 : return std::accumulate(c.cbegin(), c.cend(), 0.0, [&pmem](const Member &sum, const Element &e) { return sum + e.*pmem; });
344 : }
345 :
346 : template <typename T>[[nodiscard]] T maxval(EPVector<T> const &a)
347 : {
348 : auto max = std::max_element(a.begin(), a.end());
349 : if (max == a.end()) {
350 : return std::numeric_limits<T>::lowest();
351 : }
352 : return *max;
353 : }
354 :
355 : } // namespace EnergyPlus
356 :
357 : #endif
|