Line data Source code
1 : // EnergyPlus, Copyright (c) 1996-2023, 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 2386750 : 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 73013672780 : [[nodiscard]] T &operator[](size_type n)
78 : {
79 73013672780 : return std::vector<T>::at(n);
80 : }
81 :
82 12225809 : [[nodiscard]] const T &operator[](size_type n) const
83 : {
84 12225809 : return std::vector<T>::at(n);
85 : }
86 : #endif
87 :
88 72984133314 : [[nodiscard]] T &operator()(size_type n)
89 : {
90 72984133314 : return (*this)[n - 1];
91 : }
92 :
93 1010333 : [[nodiscard]] const T &operator()(size_type n) const
94 : {
95 1010333 : return (*this)[n - 1];
96 : }
97 :
98 133635 : void allocate(size_type size)
99 : {
100 133635 : m_allocated = true;
101 133635 : std::vector<T>::resize(size);
102 133635 : std::fill(begin(), end(), T{});
103 133635 : }
104 :
105 17522 : void deallocate() noexcept
106 : {
107 17522 : m_allocated = false;
108 17522 : std::vector<T>::clear();
109 17522 : }
110 :
111 8731 : void clear() noexcept
112 : {
113 8731 : m_allocated = false;
114 8731 : std::vector<T>::clear();
115 8731 : }
116 :
117 27941 : void resize(size_type count)
118 : {
119 27941 : m_allocated = true;
120 27941 : std::vector<T>::resize(count);
121 27941 : }
122 :
123 771 : void resize(size_type count, const T &value)
124 : {
125 771 : m_allocated = true;
126 771 : std::vector<T>::resize(count, value);
127 771 : }
128 :
129 130053725 : [[nodiscard]] bool allocated() const noexcept
130 : {
131 130053725 : return m_allocated || !this->empty();
132 : }
133 :
134 : // operator= used for initialization of the vector
135 291998075 : void operator=(const T &v)
136 : {
137 291998075 : std::fill(this->begin(), this->end(), v);
138 291998075 : }
139 :
140 : // dimension is often used to initalize the vector instead of allocate + operator=
141 4628 : void dimension(std::size_t size, const T &v)
142 : {
143 4628 : std::vector<T>::clear();
144 4628 : std::vector<T>::resize(size, v);
145 4628 : }
146 :
147 : // isize needed for current FindItemInList
148 1330374 : [[nodiscard]] int isize() const noexcept
149 : {
150 1330374 : 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 : [[nodiscard]] std::uint8_t &operator[](std::size_t n)
177 : {
178 : 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 : [[nodiscard]] std::uint8_t &operator()(size_type n)
187 : {
188 : 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 : [[nodiscard]] bool allocated() const noexcept
208 : {
209 : return m_allocated || !this->empty();
210 : }
211 :
212 : void allocate(size_type size)
213 : {
214 : m_allocated = true;
215 : std::vector<std::uint8_t>::resize(size);
216 : std::fill(begin(), end(), false);
217 : }
218 :
219 : void deallocate() noexcept
220 : {
221 : m_allocated = false;
222 : std::vector<std::uint8_t>::clear();
223 : }
224 :
225 : void clear() noexcept
226 : {
227 : m_allocated = false;
228 : std::vector<std::uint8_t>::clear();
229 : }
230 :
231 : void resize(size_type count)
232 : {
233 : m_allocated = true;
234 : std::vector<std::uint8_t>::resize(count);
235 : }
236 :
237 : void resize(size_type count, const bool &value)
238 : {
239 : m_allocated = true;
240 : std::vector<std::uint8_t>::resize(count, value);
241 : }
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 129904690 : template <typename T>[[nodiscard]] bool allocated(EPVector<T> const &v) noexcept
267 : {
268 129904690 : return v.allocated();
269 : }
270 :
271 613 : template <typename T>[[nodiscard]] auto isize(const EPVector<T> &v) noexcept
272 : {
273 613 : return v.isize();
274 : }
275 :
276 : [[nodiscard]] inline bool all(EPVector<bool> const &values) noexcept
277 : {
278 : if (values.empty()) return true;
279 : for (auto v : values) {
280 : if (!v) return false;
281 : }
282 : return true;
283 : }
284 :
285 : [[nodiscard]] inline bool any(EPVector<bool> const &values) noexcept
286 : {
287 : if (values.empty()) return false;
288 : for (auto v : values) {
289 : if (v) return true;
290 : }
291 : return false;
292 : }
293 :
294 : [[nodiscard]] inline std::size_t count(EPVector<bool> const &values) noexcept
295 : {
296 : std::size_t c(0u);
297 : for (auto v : values) {
298 : if (v) ++c;
299 : }
300 : return c;
301 : }
302 :
303 : template <typename T>[[nodiscard]] EPVector<T> pack(EPVector<T> const &v, EPVector<bool> const &mask)
304 : {
305 : EPVector<T> r;
306 : r.reserve(mask.size());
307 : for (std::size_t i = 0; i < mask.size(); ++i) {
308 : if (mask[i]) {
309 : r.emplace_back(v[i]);
310 : }
311 : }
312 : return r;
313 : }
314 :
315 : template <typename T>[[nodiscard]] Array1D<T> pack(Array1<T> const &a, EPVector<bool> const &mask)
316 : {
317 : Array1D<T> r;
318 : r.reserve(mask.size());
319 : for (std::size_t i = 0, e = mask.size(); i < e; ++i) {
320 : if (mask[i]) {
321 : r.emplace_back(a[i]);
322 : }
323 : }
324 : return r;
325 : }
326 :
327 : template <typename T>[[nodiscard]] T magnitude_squared(const EPVector<T> &v)
328 : {
329 : return std::inner_product(v.begin(), v.end(), v.begin(), T{});
330 : }
331 :
332 : template <typename T, typename V>[[nodiscard]] T dot(const EPVector<T> &u, const V &v)
333 : {
334 : return std::inner_product(u.begin(), u.end(), v.begin(), T{});
335 : }
336 :
337 766 : template <typename Element, typename Member>[[nodiscard]] Member maxval(EPVector<Element> const &a, Member Element::*pmem)
338 : {
339 766 : Member v(a.empty() ? std::numeric_limits<Member>::lowest() : a(1).*pmem);
340 732710 : for (int i = 2, e = a.isize(); i <= e; ++i) {
341 731944 : v = std::max(v, a(i).*pmem);
342 : }
343 766 : return v;
344 : }
345 :
346 : // Sum of All Members of a Container
347 2213 : template <typename Element, typename Member> inline Member sum(EPVector<Element> const &c, Member Element::*pmem)
348 : {
349 2213 : Member s(0);
350 16371 : for (const auto &elem : c) {
351 14158 : s += elem.*pmem;
352 : }
353 2213 : return s;
354 : }
355 :
356 : template <typename T>[[nodiscard]] T maxval(EPVector<T> const &a)
357 : {
358 : auto max = std::max_element(a.begin(), a.end());
359 : if (max == a.end()) {
360 : return std::numeric_limits<T>::lowest();
361 : }
362 : return *max;
363 : }
364 :
365 : } // namespace EnergyPlus
366 :
367 : #endif
|